第7周-集合


1. 本周学习总结

以你喜欢的方式(思维导图或其他)归纳总结集合相关内容。

1.1 Iterator<E> iterator(); //iterator()返回一个实现了Iterator接口的对象,可用该Iterator(迭代器)依次访问集合中的元素
For each循环遍历:(for(String element : C) do sth;)。可以与任何实现了Iterator接口的对象一起工作;任何集合都可使用。
1.2 Set中的对象:不按特定方式排序,无重复对象,最多有一个null元素
HashSet:后台使用HashMap实现,加入的类需复写equals和hashCode
TreeSet:内部使用红黑树实现,为有序集合,支持两种排序方式:Comparable和Comparator
1.3 Queue队列:有方法:
offer();//队列后端加入返回true or false
poll();//取出队头元素相当于出队,若无返回null
peek();//查看队头元素不出队,如没有返回null
1.4 Map:每一个元素都包括一对键对象和值对象,键对象不允许重复,且要覆写equals和hashCode方法
其中有三个视图:
Set<k> keySet();//键集
Collection<k> values();//值集合(不是集)
Set<Map.Entry<K, V>> entrySet();//键/值对集
用法:put();//向集合中加入元素
get();//检索与键对象对应的值对象

2. 书面作业 ArrayList代码分析

1.1 解释ArrayList的contains源代码

答:解释如下:

public boolean contains(Object o) {
return indexOf(o) >= 0;
} //判断动态数组中是否存在元素“o”
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i] == null)
return i;
} //返回第一次当“o == null”时元素的位置
else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
} //返回数组中第一次与“o”一致的元素的位置
return -1; //若数组中没有与“o”相同的元素,则...
}
public int lastIndexOf(Object o) {
if (o == null) {
for (int i = size - 1; i >= 0; i--)
if (elementData[i] == null)
return i;
} //返回最后一次当“o == null”时元素的位置
else {
for (int i = size - 1; i >= 0; i--)
if (o.equals(elementData[i]))
return i;
}//返回数组中最后一次与“o”一致的元素的位置
return -1; //若数组中没有与“o”相同的元素,则返回-1
}

1.2 解释E remove(int index)源代码

答:解释如下:

/**
* 删除指定索引位置index下的元素,返回被删除的元素
*/
public E remove(int index) {
RangeCheck(index); //检查索引范围,具体代码分析见下题
E oldValue = (E) elementData[index];//被删除的元素存到oldValue中
fastRemove(index);
return oldValue;
}
/*
* 删除单个位置的元素,是ArrayList的私有方法
*/
private void fastRemove(int index) {
modCount++;//详解如下所示
int numMoved = size - index - 1;
if (numMoved > 0)//如果删除的不是最后一个元素时
System.arraycopy(elementData, index + 1, elementData, index,numMoved);//删除的元素到最后的元素整块前移
elementData[--size] = null; //将最后一个元素设为null,在下次垃圾收集的时候就会回收掉了
}

modCount:记录ArrayList结构性变化的次数,所谓结构性变化即add(),remove()等操作。在使用迭代器遍历的时候,它可以用来检查列表中的元素是否发生结构性变化(列表元素数量发生改变),主要在多线程环境下需要使用,防止一个线程正在迭代遍历,另一个线程修改了这个列表的结构。

PS:由于还没接触到异常和线程的内容,所以在百度上找了解释,总体上知道它的作用是避免出现异常。

1.3 结合1.1与1.2,回答ArrayList存储数据时需要考虑元素的类型吗?

不需要。因为ArrayList存储数据时可以将元素的类型转换为Object,所以往ArrayList里面添加不同类型的元素是不会出错的。但是当调用ArrayList方法的时候,要传递所有元素都可以正确转型的类型,或者是Object类型,不然的话就会抛出无法转型的异常。

1.4 分析add源代码,回答当内部数组容量不够时,怎么办?

答:使用ensureCapacity()方法扩容,add源代码中扩容部分,分析如下:

/**
* 当数组的容量不够存放新加入的元素时,则使用该方法扩容
*/
public void ensureCapacity(int minCapacity) {
modCount++;//上题有解释
int oldCapacity=elementData.length;//获取数组大小(即当前数组的容量)
if (minCapacity > oldCapacity) { //在数组满了,又有新元素加入的情况下,执行扩容操作
Object oldData[] = elementData;
int newCapacity = (oldCapacity * 3) / 2 + 1;//新容量为旧容量的1.5倍+1
if (newCapacity < minCapacity)//如果扩容后的新容量还是没有传入的所需的最小容量大或等于(主要发生在addAll(Collection<? extends E> c)中)
newCapacity = minCapacity; //将新容量设为最小容量
elementData = Arrays.copyOf(elementData, newCapacity); //复制新容量
}
}

1.5 分析private void rangeCheck(int index)源代码,为什么该方法应该声明为private而不声明为public?

答:分析如下:

/**
* 检查索引index是否超出size-1
*/
private void RangeCheck(int index) {
if (index >= size)
throw new IndexOutOfBoundsException("Index:"+index+",Size:"+size);//抛出异常
}
这里对index进行了索引检查,是为了将异常内容写的详细一些并且将检查的内容缩小(index<0||index>=size,这里的size是指已存储元素的个数)。
由此可知,这是程序内部自动检查的方法,不能被外界篡改,所以应该使用private而不是public

2. HashSet原理

2.1 将元素加入HashSet(散列集)中,其存储位置如何确定?需要调用那些方法?

答:一不小心百度到了答案,理解了一遍之后整理如下:

在往HashSet存入元素的时候,它首先得调用hashCode方法得到元素对应的哈希码值,然后将哈希码值进行计算,算出元素在哈希表的位置。如果算出来的位置要是没有值,那么毫无疑问直接将元素添加到哈希表中。如果算出来的位置上有值,就调用equals方法比较已存在的值与要加入的元素的值,如果比较结果为真,那么元素相同,HashSet不允许元素重复,则不能添加。如果比较结果为假,那么就添加进哈希表(通过散列冲突的解决办法解决)。

2.2 选做:尝试分析HashSet源代码后,重新解释1.1

答:解释如下:

/**
* 当且仅当此set包含一个满足(o==null ? e==null : o.equals(e))的e元素时,返回true。
* 调用HashMap的containsKey返回映射是否包含对(key)的映射关系
* 再调用containsKey方法中的的getEntry返回是否存在(key)
* HashSet的所有元素就是通过HashMap的key来保存的
*/
public boolean contains(Object o) {
return map.containsKey(o);
} public boolean containsKey(Object key) {
return getEntry(key) != null;
} //如果此映射包含对于指定键(key)的映射关系,则返回true final Entry<K,V> getEntry(Object key) { //通过key获取一个value
int hash = (key == null) ? 0 : hash(key.hashCode());//如果key为null,则hash为0,否则用hash函数预处理
for (Entry<K,V> e = table[indexFor(hash, table.length)]; e != null; e = e.next) { //得到对应的hash值的桶,如果这个桶不是,就通过next获取下一个桶
Object k;
if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k))))
return e;
}//如果hash值相等,并且key相等则证明这个桶里的东西是我们想要的
return null; //所有桶都找遍了,没找到想要的,所以返回null
}

3. ArrayListIntegerStack题集jmu-Java-05-集合之5-1 ArrayListIntegerStack

3.1 比较自己写的ArrayListIntegerStack与自己在题集jmu-Java-04-面向对象2-进阶-多态、接口与内部类中的题目5-3自定义接口ArrayIntegerStack,有什么不同?(不要出现大段代码)

5-1:
class ArrayListIntegerStack implements IntegerStack{
private List<Integer> list;
public ArrayListIntegerStack() {
list = new ArrayList<Integer>();
}
5-3:
class ArrayIntegerStack implements IntegerStack {
private Integer[] arr;
private int top=0;
public ArrayIntegerStack(int n) {
arr=new Integer[n];
}
由以上代码可以看出,这两个实验最大的区别在于他们使用的存储数据的方式。5-3的使用了普通数组,其存储空间有限,适合在已知数据长度时使用,5-1的使用了动态数组,它具有容量扩充性,在定义的时候不需要规定长度,可以在使用时随意伸缩数组长度,比较适合我们平时的使用需求。

3.2 简单描述接口的好处.

接口是一系列方法的声明与特征的集合,把方法的特征和方法的实现分割开来,因此,这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的功能,使用起来很方便,省事。其次,接口弥补了类不能多继承的缺点,一个类可以实现多个接口,一个接口也可以在多个类上实现。

4. Stack and Queue

4.1 编写函数判断一个给定字符串是否是回文,一定要使用栈,但不能使用java的Stack类(具体原因自己搜索)。请粘贴你的代码,类名为Main你的学号。

4.2 题集jmu-Java-05-集合之5-6,银行业务队列简单模拟。(不要出现大段代码)



5. 统计文字中的单词数量并按单词的字母顺序排序后输出。题集jmu-Java-05-集合之5-2,统计文字中的单词数量并按单词的字母顺序排序后输出 (不要出现大段代码)

5.1 实验总结

部分代码如下:
Set<String> set = new TreeSet<String>();//这里使用了TreeSet作为容器收集数据,主要是为了后面的对象的排序
Iterator<String> i = set.iterator();
int sum = 0;//计数器,通过计数实现十个对象的输出
boolean flag = true;//状态标示值,通过状态的转变实现输出的继续与停止
while (i.hasNext()==flag ) {//这里的hasNext()是set接口 下的一个方法,当还有可读对象时返回true,我也就是利用了这一点来实现了输出的停止
if (sum == 9) {
flag = false;
}
sum += 1;
System.out.println(i.next());
}
在这个实验中,最主要的问题在于如何输出set中的部分值,虽然知道可以用Iterator解决,可是具体的使用也并不是很清晰。所以在百度的帮助下,我才想到了使用计数器sum以及状态标示值flag来实现部分输出,具体分析如上所示。

6. 选做:加分考察-统计文字中的单词数量并按出现次数排序,题集jmu-Java-05-集合之5-3,统计文字中的单词数量并按出现次数排序(不要出现大段代码)

6.1 伪代码

答:

while(in.hasNext()){
for (int i = 0; i < str.length; i++) {
if(tm.containsKey(s)){ //如果map中已经存在s的话
int num = tm.get(s);
tm.put(s, num+1);
}
else tm.put(s, 1);
//循环将str的值赋给s,然后加入到map,如果map已经有了s,则num+1;否则对应的值对象为1
}
if(st.equals("!!!!!")) { break;}
}
list.addAll(tm.keySet());
for (int i = 1; i < list.size(); i++) {
for (int j = 0; j < list.size()-i; j++) {
if(tm.get(j) > tm.get(j+1)){
list.set(j, list.get(j+1));
list.set(j+1, key);
} //通过冒泡进行值对象排序,每个键对象对应的map的值对象通过get()得到
}
}

6.2 实验总结

因为我只做出来了一半,所以我也只能总结一半了,有关于这个伪代码的解析在上面已经分析了。在这里主要想总结的是map的用法,真的要灵活使用,keySet();get(key);containsKey()等等,这些都是可以将value和key单独抽出来进行操作,以及和list等的转换。然后剩下的一半是value相同时对key降序排列,大概知道要怎么写这个代码,但是实际上写的时候又无从下手,我再琢磨琢磨。

7. 面向对象设计大作业-改进

7.1 完善图形界面(说明与上次作业相比增加与修改了些什么)

7.2 使用集合类改进大作业

这次稍微完善了一下数据的显示,之前的那个太小了;还有就是美化了整体的界面;还有就是之前的一些设计不大合理,然后这次就改得更人性化一点。
截图如下:

3. 码云上代码提交记录及PTA实验总结

3.1. 码云代码提交记录

在码云的项目中,依次选择“统计-Commits历史-设置时间段”, 然后搜索并截图

201521123071 《JAVA程序设计》第七周学习总结的更多相关文章

  1. 201521123027 <java程序设计>第七周学习总结

    1.本周学习总结 2.书面作业 Q1.ArrayList代码分析 1.1 解释ArrayList的contains源代码 答: 源代码: //contains()方法 public boolean c ...

  2. 201871010106-丁宣元 《面向对象程序设计(java)》第七周学习总结

    201871010106-丁宣元 <面向对象程序设计(java)>第七周学习总结 正文开头: 项目 内容 这个作业属于哪个课程 https://home.cnblogs.com/u/nwn ...

  3. 20145213《Java程序设计》第九周学习总结

    20145213<Java程序设计>第九周学习总结 教材学习总结 "五一"假期过得太快,就像龙卷风.没有一点点防备,就与Java博客撞个满怀.在这个普天同庆的节日里,根 ...

  4. 21045308刘昊阳 《Java程序设计》第九周学习总结

    21045308刘昊阳 <Java程序设计>第九周学习总结 教材学习内容总结 第16章 整合数据库 16.1 JDBC入门 16.1.1 JDBC简介 数据库本身是个独立运行的应用程序 撰 ...

  5. 20145236 《Java程序设计》第九周学习总结

    20145236 <Java程序设计>第九周学习总结 教材学习内容总结 第十六章 整合数据库 JDBC简介 1.JDBC是java联机数据库的标准规范.它定义了一组标准类与接口,标准API ...

  6. 20155304田宜楠2006-2007-2 《Java程序设计》第一周学习总结

    20155304田宜楠2006-2007-2 <Java程序设计>第一周学习总结 教材学习内容总结 - 浏览教材,根据自己的理解每章提出一个问题 第一章 除了书上提到的开发工具还有什么适合 ...

  7. 20155303 2016-2017-2 《Java程序设计》第二周学习总结

    20155303 2016-2017-2 <Java程序设计>第二周学习总结 教材学习内容总结 『注意』 "//"为单行批注符: "/*"与&quo ...

  8. 20145237 《Java程序设计》第九周学习总结

    20145237 <Java程序设计>第九周学习总结 教材学习内容总结 第十六章 整合数据库 JDBC入门 ·数据库本身是个独立运行的应用程序 ·撰写应用程序是利用通信协议对数据库进行指令 ...

  9. 20175209 《Java程序设计》第九周学习总结

    20175209 <Java程序设计>第九周学习总结 一.教材知识点总结 有关数据库下载中存在可能出现的问题已经在博客<数据库安装和使用过程中出现的一些问题>给出了相应的解决办 ...

  10. 20175317 《Java程序设计》第九周学习总结

    20175317 <Java程序设计>第九周学习总结 学前准备 首先下载XAMPP,下载完成后打开: 将前两个选项打开 在IDEA中配置驱动mysql-connector-java-5.1 ...

随机推荐

  1. CSS中2d转换:transition过渡放在:hover伪类中与应用在整个元素中区别

    css的2d转换十分强大,能够在不使用js的情况下,实现页面的元素与用户之间更多动态的交互,增强用户体验.其中使用最多的就是hover伪类. 1.创建一个页面的div元素: <!DOCTYPE ...

  2. 【HTTP权威指南】第三章-HTTP报文

    HTTP是因特网的信使,报文就是信使运送的包裹. 这一章包含: 报文如何流动 报文的三个组成部分(起始行,首部,实体的主体部分) 请求报文和响应报文的区别 请求报文支持的各种功能(方法) 响应报文返回 ...

  3. shell变量的替换,命令的替换,转义字符

    1,shell变量的替换 变量可以根据变量是否为空或者被删除,而被替换为特定的值 ${var}  变量本来的值 $(var:-word)   如果变量为空,或者已被删除那么返回word,但是不改变va ...

  4. MySQL数据库IO问题

    --MySQL数据库IO问题 ----------------------2014/05/25     看http://www.mysqlperformanceblog.com 的时候,发现Perco ...

  5. XP oracle32位客户端安装找不到orandce11.dll.dbl

    同事在XP上装oracle客户端,遇到下面的问题,mark一下. 提示找不到:orandce11.dll.dbl 点继续还会提示这个文件:orancds11.dll.dbl 网上找到解决方法: 删除注 ...

  6. c++中类对象的内存对齐

    很多C++书籍中都介绍过,一个Class对象需要占用多大的内存空间.最权威的结论是: *非静态成员变量总合.(not static) *加上编译器为了CPU计算,作出的数据对齐处理.(c语言中面试中经 ...

  7. ASP.NET Core Razor页面 vs MVC

    作为.NET Core 2.0发行版的一部分,还有一些ASP.NET的更新.其中之一是添加了一个新的Web框架来创建"页面",而不需要复杂的ASP.NET MVC.新的Razor页 ...

  8. android之使用GridView+仿微信图片上传功能

    由于工作要求最近在使用GridView完成图片的批量上传功能,我的例子当中包含仿微信图片上传.拍照.本地选择.相片裁剪等功能,如果有需要的朋友可以看一下,希望我的实际经验能对您有所帮助. 直接上图,下 ...

  9. windows10企业版怎么关闭自动更新

    windows10企业版怎么关闭自动更新..  我之所以选择关闭自动的更新的原因: 1.Windows版本是激活版的不是注册版的<其实我想说的是我用的是盗版的> 2.对于为什么禁止[系统更 ...

  10. 利用CoreAnimation实现一个时间的进度条

    (个人原创,转载请注明出处 http://www.cnblogs.com/pretty-guy/p/7460334.html) 在iOS中实现进度条通常都是通过不停的设置progress来完成的,这样 ...