第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历史-设置时间段”, 然后搜索并截图