201521123011 《java程序设计》 第7周学习总结

1. 本周学习总结

参考资料:
XMind

2. 书面作业

1.ArrayList代码分析
1.1 解释ArrayList的contains源代码
1.2 解释E remove(int index)源代码
1.3 结合1.1与1.2,回答ArrayList存储数据时需要考虑元素的类型吗?
1.4 分析add源代码,回答当内部数组容量不够时,怎么办?
1.5 分析private void rangeCheck(int index)源代码,为什么该方法应该声明为private而不声明为public?

答:
1.1

//contains()方法
public boolean contains(Object o) {
    return indexOf(o) >= 0;
}

//indexOf()方法
public int indexOf(Object o) {
    if (o == null) {
        for (int i = 0; i < size; i++)
            if (elementData[i]==null)
                return i;
    } else {
        for (int i = 0; i < size; i++)
            if (o.equals(elementData[i]))
                return i;
    }
    return -1;
}

首先比较了数组下标o,若onull那么看elementData[]中有没有null,若有就返回下标,若没有就返回-1。如果o!==null,那么就用equals方法看o与elementData[]有没有相同的情况,若有就返回下标,没有就返回-1。

1.2

//remove代码
public E remove(int index) {
    rangeCheck(index);

    modCount++;
    E oldValue = elementData(index);

    int numMoved = size - index - 1;
    if (numMoved > 0)
        System.arraycopy(elementData, index+1, elementData, index,
                         numMoved);
    elementData[--size] = null; // clear to let GC do its work

    return oldValue;
}


//rangeCheck代码
private void rangeCheck(int index) {
    if (index >= size)
        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}

用rangeCheck()看是否超过边界,int numMoved = size - index - 1,当移除一个元素时就将后一个元素向前移,删除这个元素就是把elementData[]置为null。检查要删除位置如果超过size就显示new IndexOutOfBoundsException。

1.3
不需要,因为其参数为Objcet类型的对象,Object类又是所有类的父类。无论什么类型进去都可以转换类型。

1.4

public boolean add(E e) {
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    elementData[size++] = e;
    return true;
}
//这里先保证传入的数组长度为size+1
private void ensureCapacityInternal(int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
    }

    ensureExplicitCapacity(minCapacity);
}
//如果elementData是默认长度的空数组的话,那么就确保数组容量是传入参数和默认长度的最大值,也就是说这边至少开大小为10的数组

private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);//如果需要的数组长度比现有的长度长就用grow()
    }

private void grow(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + (oldCapacity >> 1);
//newCapacity 就是扩容的新组数大小。而扩容的大小是根据原有旧数组大小来决定的,oldCapacity >>1。就是右移1位,这里会换算成二进制来进行。就是把十进制对应的数字换成二进制后往右边移一位。所以跟除以2差不多。所以扩容为原来的1.5倍。
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0)//判断有没超过最大限制
        newCapacity = hugeCapacity(minCapacity);
    // minCapacity is usually close to size, so this is a win:
    elementData = Arrays.copyOf(elementData, newCapacity);
}

private static int hugeCapacity(int minCapacity) {
    if (minCapacity < 0) // overflow
        throw new OutOfMemoryError();
    return (minCapacity > MAX_ARRAY_SIZE) ?
        Integer.MAX_VALUE :
        MAX_ARRAY_SIZE;
}

1.5

private void rangeCheck(int index) {
    if (index >= size)
        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
} 

rangeCheck就是看数组是否越界,不需要外部的进行修改或者访问。所以没必要用public声明。

2.HashSet原理
2.1 将元素加入HashSet(散列集)中,其存储位置如何确定?需要调用那些方法?
2.2 选做:尝试分析HashSet源代码后,重新解释1.1

答:
2.1
HashSet实际上是后台用HashMap实现
HashSet是通过Set接口来实现,Set没有重复对象,所以存入Set的每个元素都必须是唯一的。加入HashSet的类应该覆写equals()与hashCode(),保证这两个方法返回结果一致。

3.ArrayListIntegerStack
题集jmu-Java-05-集合之5-1 ArrayListIntegerStack
3.1 比较自己写的ArrayListIntegerStack与自己在题集jmu-Java-04-面向对象2-进阶-多态、接口与内部类中的题目5-3自定义接口ArrayIntegerStack,有什么不同?(不要出现大段代码)
3.2 简单描述接口的好处.

答:
3.1

class ArrayIntegerStack implements IntegerStack {
       private List<Integer> list;
public ArrayIntegerStack() {
	list= new ArrayList <Integer>();
	
}
	@Override
	public Integer push(Integer item) {
		if(item==null)
		return null;
		list.add(item);
		return item;
		
	}


//对比
public class ArrayIntegerStack implements IntegerStack {
	private Integer[]arr;
	private int top=0;


	public ArrayIntegerStack(int n) {
		arr=new Integer[n];
	}

	@Override
	public Integer push(Integer item) {
		// //如果item为null,则不入栈直接返回null。如果栈满,也返回null。如果插入成功,返回item。
		if(item==null)
			return null;
		if(top==arr.length)
			return null;
		arr[top++]=item;
		return item;
	}

ArrayListIntegerStack是用ArrayList来实现栈,ArrayIntegerStack是用Integer数组来实现栈。
ArrayIntegerStack是会存在栈满的情况,而ArrayListIntegerStack不存在。
ArrayIntegerStack在进出栈的时候需要用到top指针ArrayListIntegerStack不需要,调用remove()方法就可以。

3.2
对于这一例来说,两者都继承了一个接口IntegerStack,就可以使用一个接口来操作不同的类

4.Stack and Queue
4.1 编写函数判断一个给定字符串是否是回文,一定要使用栈,但不能使用java的Stack类(具体原因自己搜索)。请粘贴你的代码,类名为Main你的学号。
4.2 题集jmu-Java-05-集合之5-6 银行业务队列简单模拟。(不要出现大段代码)

答:
4.1

class ArrayListStringStack implements StringStack{
    private List<String> list;
    
    public ArrayListStringStack() {
        list=new ArrayList<String>();
    }
    @Override
    public String push(String item) {
        // TODO Auto-generated method stub
        if(item==null)
            return null;
        list.add(item);
        return item;
    }

    @Override
    public String pop() {
        // TODO Auto-generated method stub
        if(list.isEmpty())
            return null;
        return list.remove(list.size()-1);
    }

}

public class Main201521123011 {
    public static void main(String[] args) {

        Scanner sc=new Scanner(System.in);
        String s=sc.nextLine();
        stackString str=new stackString(s);
        for(int i=0;i<str.size();i++)
        {
            if(s.charAt(i)!=str.pop())
            {
                System.out.println("flase");
                return;
            }
        }

        System.out.println("true");


    }
}

4.2
使用Queue接口,用两个队列,一个存放偶数,一个存放奇数。

for (int i = 1; i <= n; i++) {
int sc = scanner.nextInt();
if (sc % 2 == 0) {
    a.offer(x);
} else {
    b.offer(x);
}
}
 while(!link1.isEmpty()||!link2.isEmpty())
        {
            Integer a=link1.poll();
            if(a!=null)
            {
                if(link1.isEmpty()&&link2.isEmpty())
                System.out.println(a);
                else
                System.out.print(a+" ");
            }
            Integer b=link1.poll();
            if(b!=null)
            {
                if(link1.isEmpty()&&link2.isEmpty())
                System.out.println(b);
                else
                System.out.print(b+" ");
            }

               
            

5.统计文字中的单词数量并按单词的字母顺序排序后输出
题集jmu-Java-05-集合之5-2 统计文字中的单词数量并按单词的字母顺序排序后输出 (不要出现大段代码)
5.1 实验总结

public class Main {
	public static void main(String[] args) {
		Queue<String> q = new ArrayDeque<String>();
		Stack<String> stack = new Stack<String>();
		Set<String> arr = new TreeSet<String>();
                List<String> strlist = new ArrayList<String>();
		Queue<String> strList;

		System.out.println(strList);
		for (int i = 0; i < strList.size(); i++) {
			if (strList.get(i).equals("1"))
				strList.remove(i);
		}
		System.out.println(strList);

		Scanner sc = new Scanner(System.in);
		if (str.equals("!!!!"))
			break;
		System.out.println(str);

		int i = 0;
		for (String s : arr) {
			if (i == 10)
				break;
			else if (i > arr.size())
				break;
			System.out.println(s);
			i++;
		}

5.1
使用了Set的自然排序实现类TreeSet,TreeSet实现有序排列。
当时用remove方法时,总会获得当前优先级队列中最小的元素。

3. 码云上代码提交记录及PTA实验总结

题目集:jmu-Java-05-集合
3.1. 码云代码提交记录

posted @ 2017-04-08 14:48  叫我小天才  阅读(297)  评论(1编辑  收藏  举报