8
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;
}
解释:先判断对象是否为空,如果是,则遍历数组查看是否有null,若存在返回下标,没有则返回-1。若对象不为空,则用equals()比较数组中是否有与o相同的对象,有则返回下标没有则返回-1。
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;
return oldValue;
}
解释:首先检查是否在范围内,然后删除元素,被删除的元素存到oldValue中,删除后的元素整体前移一位,把移除后的空位置设为null。
1.3 结合1.1与1.2,回答ArrayList存储数据时需要考虑元素的具体类型吗?
不需要,ArrayList是动态数组,在存储数据的时候可以改变类型,变成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) { // elementData为默认长度
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); // 传入参数,默认长度
}
ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) { // 每调用一次就增加一次
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0) //如果数组长度不足就调用grow()
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);
}
1.5 分析private void rangeCheck(int index)源代码,为什么该方法应该声明为private而不声明为public?
rangeCheck用来判断数组是否越界,是内部调用,不需要别人了解是如何调用的,所以声明为private。
2. HashSet原理
2.1 将元素加入HashSet(散列集)中,其存储位置如何确定?需要调用那些方法?
当向HashSet中添加一个元素时,HashSet会调用该对象的hashCode()方法得到其hashCode值,然后根据该值决定该对象的存储位置,但是如果有两个元素通过equals()方法比较返回true,而它们的hashCode()方法返回值不等,HashSet也会将它们存储在不同的位置。
方法:hashCode()方法、equals()方法
2.2 将元素加入HashSet中的时间复杂度是多少?是O(n)吗?(n为HashSet中已有元素个数)
将元素加入HashSet中的时间复杂度是O(1),不是O(n),因为可以直接加入,和元素个数无关
3. ArrayListIntegerStack
题集jmu-Java-05-集合之ArrayListIntegerStack
3.1 比较自己写的ArrayListIntegerStack与自己在题集jmu-Java-04-面向对象2-进阶-多态、接口与内部类中的题目自定义接口ArrayIntegerStack,有什么不同?(不要出现大段代码)
ArrayListIntegerStack是用List列表存储元素的,而采ArrayIntegerStack采用的是数组的形式存储的。
3.2 结合该题简单描述接口的好处,需以3.1为例详细说明,不可泛泛而谈。
对于这道题,两个ArrayIntegerStack方法接口内部名称都相同,但是对IntegerStack接口的实现不同进行不同,所以好处便是对要完成功能相似但是实现方法不一样的,可以使用的方法名称相同但是实现方法可以不同,来根据不同的需求来用不同的方法去实现
。
4. Stack and Queue
4.1 编写函数判断一个给定字符串是否是回文,一定要使用栈(请利用Java集合中已有的类),但不能使用java的Stack类(具体原因自己搜索)与数组。请粘贴你的代码,类名为Main你的学号。
4.2 题集jmu-Java-05-集合之银行业务队列简单模拟(只粘贴关键代码)。请务必使用Queue接口,并说明你使用了Queue接口的哪一个实现类?
//定义两个队列
Queue<Integer> listA = new LinkedList<Integer>();
Queue<Integer> listB = new LinkedList<Integer>();
//入队
for (int i = 0; i < m; i++) {
int a = sc.nextInt();
if (a % 2 == 1)
listA.add(a);
else
listB.add(a);
}
类通过使用LinkedList实现。
5. 统计文字中的单词数量并按单词的字母顺序排序后输出
题集jmu-Java-05-集合之5-2 统计文字中的单词数量并按单词的字母顺序排序后输出 (作业中不要出现大段代码)
5.1 实验总结
利用 TreeSet排序,将单词按字母顺序排序输出,还有判断文章是否结束用if判断感叹号,用words.size统计单词个数。
3.码云及PTA
题目集:jmu-Java-05-集合
3.1. 码云代码提交记录
3.2 截图PTA题集完成情况图
3.3 统计本周完成的代码量
周次 | 总代码量 | 新增代码量 | 总文件数 | 新增文件数 |
---|---|---|---|---|
1 | 86 | 86 | 8 | 8 |
2 | 342 | 342 | 10 | 10 |
3 | 762 | 762 | 16 | 16 |
4 | 762 | 0 | 16 | 0 |
5 | 1229 | 967 | 24 | 8 |
6 | 1752 | 523 | 29 | 5 |
7 | 2117 | 365 | 33 | 4 |
8 | 2493 | 376 | 36 | 3 |
9 | 2887 | 511 | 43 | 7 |