第7周-集合

1. 本周学习总结

以你喜欢的方式(思维导图或其他)归纳总结集合相关内容。
参考资料:
XMind

2. 书面作业

1.ArrayList代码分析

1.1 解释ArrayList的contains源代码

源代码
public boolean contains(Object o) {
    return indexOf(o) >= 0;
}

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;
}

答:contains方法在执行后首先会调用indexOf()方法。indexOf()方法会判断传入的对象o是否为null,如果o为null,那么就去找elementData[] 是否有为null的对象,有则返回下标,没有则返回-1。如果o不为null,就通过equals去比较elementData[] 中是否有与o相同的对象,有则返回下标,没有则返回-1。最后contains还做了判断,如果indexOf()方法返回大于0,就说明集合内存在该元素,小于0则不存在。

1.2 解释E remove(int index)源代码

源代码
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;
}
private void rangeCheck(int index) {
    if (index >= size)
        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}

答:先判断移除的元素是不是在范围内,不是的话抛出IndexOutOfBoundsException异常,否则将移除元素返回,并将后面的元素往前移一位。最后用GC清理空间。
1.3 结合1.1与1.2,回答ArrayList存储数据时需要考虑元素的类型吗?
答:不需要考虑,因为ArrayList实际上是实现object数组,而object类又是所有类的父类,所以不用考虑。
1.4 分析add源代码,回答当内部数组容量不够时,怎么办?

源代码
 public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }
 private void ensureCapacityInternal(int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }

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

        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
 private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        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);
    }

答:当内部容量不够时,调用grow()方法,里面有一句int newCapacity = oldCapacity + (oldCapacity >> 1);相当于int newCapacity = oldCapacity + (oldCapacity / 2)也就是说int newCapacity = oldCapacity * (1.5)
即扩容50%的意思。
1.5 分析private void rangeCheck(int index)源代码,为什么该方法应该声明为private而不声明为public?
答:使用户不能触及到remove()方法;因为用户不需要知道执行remove()方法的时候程序是怎么做的,用户只需要知道结果,如果有错的话,会直接抛出异常。

2.HashSet原理

2.1 将元素加入HashSet(散列集)中,其存储位置如何确定?需要调用那些方法?
答:散列表用链表数组实现---〉每个列表被称为桶,确定存储位置需要计算哈希码,即调用对象的hashCode方法,根据哈希码查找到对应的桶。如果桶中已有其他元素,则调用加入对象的equals()方法与已有元素进行比较。如果比较结果为假,则将对象插入桶中。如果比较结果为真,则用新的值替换旧的值。

3.ArrayListIntegerStack

题集jmu-Java-05-集合之5-1 ArrayListIntegerStack
3.1 比较自己写的ArrayListIntegerStack与自己在题集jmu-Java-04-面向对象2-进阶-多态、接口与内部类中的题目5-3自定义接口ArrayIntegerStack,有什么不同?(不要出现大段代码)
答:区别在于ArrayIntegerStack是需要规定大小的,而ArrayListIntegerStack不需要,它可以自动扩容。其次ArrayIntegerStack需要一个top指针来进行栈的一系列操作,而ArrayListIntegerStack可以直接利用list的方法来进行栈操作。
3.2 简单描述接口的好处.
答:接口可以给定方法特征,统一规范。比如ArrayListIntegerStack和ArrayIntegerStack使用的是同一个接口,实用的方法名称一样,但是又分别根据实际情况定义了不同的方法,从而达到自己的目的。

4.Stack and Queue

4.1 编写函数判断一个给定字符串是否是回文,一定要使用栈,但不能使用java的Stack类(具体原因自己搜索)。请粘贴你的代码,类名为Main你的学号。

import java.util.*;
public class Main201521123047 {

 public static void main(String[] args) {
	 Scanner in = new Scanner(System.in);
	 String str = in.next();
	 System.out.println(isPalindrome(str));
 }
 public static boolean isPalindrome(String str){
	 List<Character>  stack1 = new ArrayList<Character>();
	 List<Character>  stack2 = new ArrayList<Character>();
	 int halflen = str.length()/2;   
	 for(int i=0;i<halflen;i++){
		 stack1.add(str.charAt(i));
		 stack2.add(str.charAt(str.length()-i-1));
  }
	 boolean Flag = true;
	 for(int i=halflen-1;i>=0;i--){
		 if(stack1.remove(i) != stack2.remove(i)){
			 Flag = false;
			 break;
		 }
	 }
	 return Flag;
 	}
}

创建两个栈,把输入的字符分两半,前一半一个正序输入,后一半一个倒序输入,之后对比两个栈即可。
4.2 题集jmu-Java-05-集合之5-6 银行业务队列简单模拟。(不要出现大段代码)
先根据奇偶把数分别放在A,B队列,然后再按题目要求输出。

	while(!A.isEmpty() || !B.isEmpty()) {
			Integer a1 = A.poll();
			if(a1 != null) {
				if(B.isEmpty() && A.isEmpty())
					System.out.print(a1);
				else 
					System.out.print(a1 + " ");	
			}
			Integer a2 = A.poll();
			if(a2 != null) {
				if(B.isEmpty() && A.isEmpty())
					System.out.print(a2);
				else 
					System.out.print(a2 + " ");	
			}
			Integer b = B.poll();
			if(b != null) {
				if(B.isEmpty() && A.isEmpty())
					System.out.print(b);
				else 
					System.out.print(b + " ");
			}
		}

5.统计文字中的单词数量并按单词的字母顺序排序后输出

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

 Set<String> set = new TreeSet();  
		
		 Scanner in = new Scanner(System.in);
		 while(in.hasNext()){
			 String s = in.next();
			 if (s.equals("!!!!!"))break;
			 set.add(s);
		 }
		 System.out.println(set.size());			 
			for (int i = 0; i < 10 ; i++) {
				System.out.println(set.toArray()[i]);
			}
	}

5.1 实验总结:根据题目要求很明显可以知道要使用Set,因为Set里面的对象是不重复的,这样才能计算单词数量,其次因为要按字母顺序排序后输出,所以知道用TreeSet,因为它有排序功能。

7.面向对象设计大作业-改进

7.1 完善图形界面(说明与上次作业相比增加与修改了些什么)
7.2 使用集合类改进大作业

与之前相比,在购物车添加的时候使用了Set,使物品添加不出现重复。
参考资料:
JTable参考项目

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

题目集:jmu-Java-05-集合

3.1. 码云代码提交记录

在码云的项目中,依次选择“统计-Commits历史-设置时间段”, 然后搜索并截图

posted @ 2017-04-08 20:30  陈大家  阅读(224)  评论(0编辑  收藏  举报