08
作业08-集合
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。
1.2 解释E remove(int index)源代码
remove(int)用于删除ArrayList数组容器中指定位置int上的元素,并返回此元素.
Java源代码
public E remove(int index) {
RangeCheck(index);
modCount++;
E oldValue = elementData[index];
//numMoved需要移动的元素个数,也就是index后面的所有的元素个数
int numMoved = size - index - 1;
//将index后面的所有元素全部往前依次移动一个位置
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
//经过arraycopy的移位,数组容器的最个位置被腾空,
//但是仍然持有某个对象的引用,需要把这个多余的引用置为null.
elementData[--size] = null; // Let gc do its work
return oldValue;
}
1.3 结合1.1与1.2,回答ArrayList存储数据时需要考虑元素的具体类型吗?
需要考虑,虽然contains源代码是Object o,但是remove是int index,方法还是规定了元素的类型才能用方法。
1.4 分析add源代码,回答当内部数组容量不够时,怎么办?
public boolean add(E paramE)
{
ensureCapacityInternal(this.size + 1);
this.elementData[(this.size++)] = paramE;
return true;
}
- 检查当前集合中是否有空间可以装下新的元素
- 如果空间不够了,会自动扩容
- 注:ArrayList会分配连续的内存片段来储存集合的元素,因为内部其实是数组
1.5 分析private void rangeCheck(int index)源代码,为什么该方法应该声明为private而不声明为public?
因为该方法想要只有他的类才能调用这个方法,其他的方法不能随意调用这个方法。
2. HashSet原理
2.1 将元素加入HashSet(散列集)中,其存储位置如何确定?需要调用那些方法?
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
要调用map.put()的方法,中又调用了以下方法。
2.2 将元素加入HashSet中的时间复杂度是多少?是O(n)吗?(n为HashSet中已有元素个数)
要看设置的hashCode,如果重写的hashCode写的好就是o(1),一般的就是o(n)。
2.3 选做:尝试分析HashSet源代码后,重新解释2.1
3. ArrayListIntegerStack
题集jmu-Java-05-集合之ArrayListIntegerStack
3.1 比较自己写的ArrayListIntegerStack与自己在题集jmu-Java-04-面向对象2-进阶-多态、接口与内部类中的题目自定义接口ArrayIntegerStack,有什么不同?(不要出现大段代码)
ArrayList或者LinkedList,作为栈的内部存储,是用列表进行储存。
04面向对象进阶-03-接口-自定义接口ArrayIntegerStack运用的是数组储存。
3.2 结合该题简单描述接口的好处,需以3.1为例详细说明,不可泛泛而谈。
接口的话可以实现不同的形态,比如ArrayListIntegerStack的话,接口里面是用list储存,接口的名字虽然一样,但是实现可以内部写不同的代码。ArrayIntegerStack虽然是用数组储存,但是方法还是一样的。
就是说这几个方法只有方法名,没有方法体,之后的类实现这个接口后,编程人员可以用各种各样不同的方式实现这个接口,比如列表实现或是数组实现,方便编程人员的使用
4. Stack and Queue
4.1 编写函数判断一个给定字符串是否是回文,一定要使用栈(请利用Java集合中已有的类),但不能使用java的Stack类(具体原因自己搜索)与数组。请粘贴你的代码,类名为Main你的学号。
package big;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
interface IntegerStack{
public Integer push(Integer item); //如item为null,则不入栈直接返回null。否则直接入栈,然后返回item。
public Integer pop(); //出栈,如栈为空,则返回null。
public Integer peek(); //获得栈顶元素,如栈顶为空,则返回null。注意:不要出栈
public boolean empty(); //如过栈为空返回true
public int size(); //返回栈中元素数量
}
class ArrayListIntegerStack implements IntegerStack{
List<Integer> str=new ArrayList<Integer>();
@Override
public Integer push(Integer item) {
// TODO Auto-generated method stub
if(item==null)
return null;
str.add(item);
return item;
}
@Override
public Integer pop() {
// TODO Auto-generated method stub
if(!str.isEmpty())
return str.remove(str.size()-1);
else
return null;
}
@Override
public Integer peek() {
// TODO Auto-generated method stub
if(!str.isEmpty())
return str.get(str.size()-1);
else
return null;
}
@Override
public boolean empty() {
// TODO Auto-generated method stub
return str.isEmpty();
}
@Override
public int size() {
// TODO Auto-generated method stub
return str.size();
}
}
public class Main201621123036 {
public static void main(String[] args) {
// TODO Auto-generated method stub
ArrayListIntegerStack qvq=new ArrayListIntegerStack();
Scanner sc = new Scanner(System.in);
String s=sc.nextLine();
boolean b=true;
int[] word=new int[s.length()];
for (int i = 0; i < word.length; i++) {
word[i]=Integer.parseInt(String.valueOf(s.charAt(i)));
}
for (int i = 0; i < word.length; i++) {
qvq.push(word[i]);
}
for (int i = 0; i < word.length; i++) {
if(!qvq.pop().equals(word[i])){
b=false;
break;
}
}
if(b==false)
System.out.println("不是回文");
else
System.out.println("是回文");
}
}
4.2 题集jmu-Java-05-集合之银行业务队列简单模拟(只粘贴关键代码)。请务必使用Queue接口,并说明你使用了Queue接口的哪一个实现类?
int x=Integer.parseInt(sc.next());
for (int i = 0; i < x; i++) {
int y=sc.nextInt();
if(y%2==0)
q2.addLast(y);
else
q1.addLast(y);
}
while(!q1.isEmpty()&&!q2.isEmpty()){
System.out.print(q1.poll()+" "+q1.poll()+" "+q2.poll()+" ");
}
while(!q1.isEmpty()){
if(q1.size()==1)
System.out.print(q1.poll());
else
System.out.print(q1.poll()+" ");
}
while(!q2.isEmpty())
if(q2.size()==1)
System.out.print(q2.poll());
else
System.out.print(q2.poll()+" ");
实现了双队列Deque的LinkedList类。
5. 统计文字中的单词数量并按单词的字母顺序排序后输出题集jmu-Java-05-集合之5-2 统计文字中的单词数量并按单词的字母顺序排序后输出 (作业中不要出现大段代码)
while(true){
String x=sc.next();
if(x.equals("!!!!!"))
break;
else{
list.add(x);
}
}
5.1 实验总结
也可以用
String[] str=sc.nextLine().split(" +");
这题如果有符号的话其实是有错误的,类似于your,
和you
不同,然后会导致重复,应该要检查每个单词是否包含特殊字符,再放入list。
6. 选做:统计文字中的单词数量并按出现次数排序
题集jmu-Java-05-集合之5-3 统计文字中的单词数量并按出现次数排序(不要出现大段代码)
6.1 伪代码
运用TreeMap,每个单词进入列表里,进入之前先判断是否存在相同的,存在移除(key,value),计数加一,重写写入列表,键值为计数,打印列表。
6.2 实验总结
7. 选做 面向对象设计大作业-改进
7.1 使用集合类改进大作业或者简述你的面向对象设计大作业中,哪里使用到了集合类。
7.2 进一步完善图形界面(仅需出现改进的后的图形界面截图)
参考资料:
JTable参考项目
3.码云及PTA
题目集:jmu-Java-05-集合
3.1. 码云代码提交记录
在码云的项目中,依次选择“统计-Commits历史-设置时间段”, 然后搜索并截图
3.2 截图PTA题集完成情况图
需要有两张图(1. 排名图。2.PTA提交列表图)
3.3 统计本周完成的代码量
需要将每周的代码统计情况融合到一张表中。
上次统计时间:2017-11-04 19:07:40
距离上次统计经过了:167小时5分钟12秒
周次 | 总代码量 | 新增代码量 | 总文件数 | 新增文件数 |
---|---|---|---|---|
1 | 0 | 0 | 0 | 0 |
2 | 0 | 0 | 0 | 0 |
3 | 0 | 0 | 0 | 0 |
4 | 0 | 0 | 0 | 0 |
5 | 0 | 0 | 0 | 0 |
6 | 1553 | 1553 | 24 | 24 |
7 | 1848 | 295 | 30 | 6 |
8 | 2902 | 1054 | 41 | 11 |
9 | 3299 | 397 | 48 | 7 |
选做:4. 使用Java解决实际问题
尝试为代码统计项目 增加图形界面。
3.1 设计图形界面(可用纸画)。
3.2 从该git项目fork一个分支,在该分支上进行你的开发,以后如果开发的好,可以尝试向开发者提出pull request。注意:规划好包名。