201521123050 《Java程序设计》第7周学习总结
1. 本周学习总结
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;
如果o为null,那么就去找elementData[] 是否有为null的对象,有则返回下标没有则返回-1。
如果o不为null,就通过equals去比较elementData[] 中是否有与o相同的对象,有则返回下标没有则返回-1。
这里判断 o==null 主要就用来确定是否要使用 o.equals(),防止出现NPE。
因为ArrayList 是可以放入null的,所以不能 elementData[i].equals(o) 。
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;
}
检测删除的位置是否超出List大小,如果超出则显示异常。类似数组删除操作,删掉某个元素后,其位置之后的元素前移。
1.3 结合1.1与1.2,回答ArrayList存储数据时需要考虑元素的类型吗?
答:不用考虑,因为类型都为Object类型,而Object又是所有类的父类,所以可以是任意类型。
1.4 分析add源代码,回答当内部数组容量不够时,怎么办?
答:
public boolean add(E e) {
ensureCapacityInternal(size + 1);
elementData[size++] = e;//添加对象时,自增size
return true;
}
方法中调用的ensureCapacityInternal主要用来调整容量,修改elementData数组的指向。其中涉及到3个方法的调用,其核心在于grow方法:
private void ensureCapacityInternal(int minCapacity) {
modCount++;//定义于ArrayList的父类AbstractList,用于存储结构修改次数
// 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);//新容量扩大到原容量的1.5倍,右移一位相关于原数值除以2。
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;//MAX_ARRAY_SIZE和Integer.MAX_VALUE为常量
}
可知java自动增加ArrayList大小的思路是:向ArrayList添加对象时,原对象数目加1如果大于原底层数组长度,则以适当长度新
建一个原数组的拷贝,并修改原数组,指向这个新建数组。原数组自动抛弃(java垃圾回收机制会自动回收)。size则在向数组添加对象,自增1。
1.5 分析private void rangeCheck(int index)源代码,为什么该方法应该声明为private而不声明为public?
答:
private void rangeCheck(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
使外部无法访问,rangeCheck方法保证了remove等操作的容量范围,如果超出则会显示异常。
2.HashSet原理
2.1 将元素加入HashSet(散列集)中,其存储位置如何确定?需要调用那些方法?
答:HashSet中add方法调用的是底层HashMap中的put()方法,而如果是在HashMap中调用put,首先会判断key是否存在,如果key存在则修改value值,如果key不存在这插入这个key-value。而在set中,因为value值没有用,也就不存在修改value值的说法,因此往HashSet中添加元素,首先判断元素(也就是key)是否存在,如果不存在这插入,如果存在着不插入,这样HashSet中就不存在重复值。
2.2 选做:尝试分析HashSet源代码后,重新解释1.1
3.ArrayListIntegerStack
题集jmu-Java-05-集合之5-1 ArrayListIntegerStack
3.1 比较自己写的ArrayListIntegerStack与自己在题集jmu-Java-04-面向对象2-进阶-多态、接口与内部类中的题目5-3自定义接口ArrayIntegerStack,有什么不同?(不要出现大段代码)
public ArrayListIntegerStack(){
this.list = new ArrayList<Integer>();
}
public ArrayIntegerStack(int n) {
this.stack = new Integer[n];
}
在于数组与动态数组的不同,ArrayList不需要用到指针,直接使用list方法进行某些操作。
3.2 简单描述接口的好处.
答:
- 1、重要性:在Java语言中, abstract class 和interface 是支持抽象类定义的两种机制。正是由于这两种机制的存在,才赋予了Java强大的 面向对象能力。
- 2、简单、规范性:如果一个项目比较庞大,那么就需要一个能理清所有业务的架构师来定义一些主要的接口,这些接口不仅告诉开发人员你需要实现那些业务,而且也将命名规范限制住了(防止一些开发人员随便命名导致别的程序员无法看明白)。
- 3、维护、拓展性:比如你要做一个画板程序,其中里面有一个面板类,主要负责绘画功能,然后你就这样定义了这个类。可是在不久将来,你突然发现这个类满足不了你了,然后你又要重新设计这个类,更糟糕是你可能要放弃这个类,那么其他地方可能有引用他,这样修改起来很麻烦。如果你一开始定义一个接口,把绘制功能放在接口里,然后定义类时实现这个接口,然后你只要用这个接口去引用实现它的类就行了,以后要换的话只不过是引用另一个类而已,这样就达到维护、拓展的方便性。
- 4、安全、严密性:接口是实现软件松耦合的重要手段,它描叙了系统对外的所有服务,而不涉及任何具体的实现细节。这样就比较安全、严密一些(一般软件服务商考虑的比较多)。
4.Stack and Queue
4.1 编写函数判断一个给定字符串是否是回文,一定要使用栈,但不能使用java的Stack类(具体原因自己搜索)。请粘贴你的代码,类名为Main你的学号。
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 统计文字中的单词数量并按单词的字母顺序排序后输出 (不要出现大段代码)
if (set.size() <= 10){
for (String string : set) {
System.out.println(string);
}
}else{
for (int i = 0; i < 10; i++) {
System.out.println(set.toArray()[i]);
}
}
6.选做:加分考察-统计文字中的单词数量并按出现次数排序
题集jmu-Java-05-集合之5-3 统计文字中的单词数量并按出现次数排序(不要出现大段代码)