201521123022 《Java程序设计》 第七周学习总结
1. 本周学习总结
以你喜欢的方式(思维导图或其他)归纳总结集合相关内容。
2. 书面作业
Q1.ArrayList代码分析
Q1.1 解释ArrayList的contains源代码
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来判断遍历时所用方法。o不为null时,用equals方法进行。而当o为null时,则判断elementData[i]是否为null。
Q1.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));
}
其中RangeCheck()的作用是判断参数index是否超出范围,若检查出要删除的位置如果超出List大小,就显示IndexOutOfBoundsException异常。若没有超出,则删除指定元素,再将位置之后的元素往前移,最后使得size-1的位置的值为null,并使GC clear it。
Q1.3 结合1.1与1.2,回答ArrayList存储数据时需要考虑元素的类型吗?
不用,Object类是所有类的父类,而在源代码中的参数都是Object类型的对象。所以ArrayList存储数据时无需考虑元素类型。
Q1.4 分析add源代码,回答当内部数组容量不够时,怎么办?
代码如下:
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
ensureCapacity()方法,它的作用是用来调整容量,保证elementData内部容量是size + 1。
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);
}
如果超出容量,则调用grow方法增加容量。
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);
}
扩容至1.5倍,也就是说新List的容量是旧的1.5倍,再把旧数组拷贝至新数组。
Q1.5 分析private void rangeCheck(int index)源代码,为什么该方法应该声明为private而不声明为public?
简单来说,用户端并不需要知道remove()的时候具体执行了哪些操作,他们只需要了解最终的结果,这并不是单纯属于代码隐私的问题,而是可以认为对用户端来说这些是无用的信息,设置为private反而利于用户端的使用。
Q2. HashSet原理
Q2.1 将元素加入HashSet(散列集)中,其存储位置如何确定?需要调用那些方法?
HashSet存储形式依靠链表数组实现。
当向HashSet中添加一个元素时,HashSet会调用该对象的hashCode()方法得到其hashCode值,然后根据该值决定该对象的存储位置,但是如果有两个元素通过equals()方法比较返回true,而它们的hashCode()方法返回值不等,HashSet也会将它们存储在不同的位置。
-- 引用自该博客
Q3. ArrayListIntegerStack
Q3.1 比较自己写的ArrayListIntegerStack与自己在题集jmu-Java-04-面向对象2-进阶-多态、接口与内部类中的题目5-3自定义接口ArrayIntegerStack,有什么不同?(不要出现大段代码)
5-5-1:
public ArrayListIntegerStack(){
list = new ArrayList<Integer>();
}
使用ArrayList,自身就可以为内部数组进行初始容量赋值并扩容。
4-5-3:
private Integer[] stack;
private int top=0;
public ArrayIntegerStack(int n){
this.stack = new Integer[n];
}
ArrayIntegerStack中则需要自行定义数组的大小,并且需要用top指针来进行删除,输出等操作。
Q3.2 简单描述接口的好处.
对本题来说,两个ArrayIntegerStack方法同名,却是对IntegerStack接口进行不同的实现。所以可以看出接口的好处之一是对要完成功能相似而具体实现方法不同的情况来说,可以用相同的方法名,不同的实现,来根据需求通过不同的方式来实现。
Q4. Stack and Queue
Q4.1 编写函数判断一个给定字符串是否是回文,一定要使用栈,但不能使用java的Stack类(具体原因自己搜索)。请粘贴你的代码,类名为Main你的学号。
部分代码如下:
public class Main201521123022 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Stack<Character> stack = new Stack<Character>();
Scanner sc = new Scanner(System.in);
String b = sc.next();
for (int i = 0; i < b.length(); i++) {
stack.push(b.charAt(i));
}
for (int j= 0; j < b.length(); j++) {
if (stack.pop() == b.charAt(j)) {
System.out.println("是");
break;
}
else {
System.out.println("否");
break;
}
}
}
}
Q4.2 题集jmu-Java-05-集合之5-6 银行业务队列简单模拟。(不要出现大段代码)
本题通过建立2个队列List1,List2分别存放奇数和偶数,List1输出2个后List2输出1个。当一个队列空时跳出循环,输出剩余元素。
Q5.统计文字中的单词数量并按单词的字母顺序排序后输出
题集jmu-Java-05-集合之5-2 统计文字中的单词数量并按单词的字母顺序排序后输出 (不要出现大段代码 )
关键代码如下:
TreeSet<String>jojo=new TreeSet<String>();
int i=0;
for(String e:jojo)
{
if(i==10) break;
System.out.println(e);
i++;
}
5.1 实验总结
使用TreeSet时,其本身有默认排序功能。而HashSet可用作无序的词汇存储。所以本题用TreeSet输出前十位字母即可。