黑马程序员-java基础-集合框架-Collection、List、Set

第一讲:体系概述

一、概述

1、  作用:用于存放对象的容器

2、  特点:只用于存储对象,集合长度可变,集合可以存储不同类型的对象;

3、  与数组的区别:虽然数据也可以存储对象,但数组的长度是固定的,而集合长度是可变的,集合类的出现可以解决现实生活中数量不确定的问题;

4、  常用的集合类及结构

         

 

 

第二讲:共性方法

集合实现了Collection接口,Collection接口声明了如下常用方法:

1)  向集合中添加元素:add(Object obj)、addAll()

add()方法用于向集合中添加对象,实际添加的并不是对象本身,而是将对象的地址添加到了集合中。如下:是将hello_1、hello_2、hello_3这三个字符串对象在堆内存中的地址添加给了ar1集合。

总结:

  • add(Object obj)方法的参数是Object,以便于接收任意类型对象;
  • 集合中存储的都是对象的引用或者地址;

 

2)  删除集合中元素:remove(Object obj)

3)  判断元素是否存在于集合中

4)  取两个集合的交集:retainAll(Collection c)

ar1.retainAll(ar2); //获取ar1和ar2中共同的元素,并最终赋给ar1。

5)  去掉交集:removeAll(),去掉两个集合中的共同元素

ar1.removeAll(ar2); //去掉ar1中与ar2相同的元素。

 

 

第三讲:迭代器

概念:定义在集合内部的,用于取出集合中的元素的方式;

       

定义迭代器来取集合中元素的原因:不同的集合,数据存放的结构不同,取的动作细节也不同,因此,不能简单的定义一个函数来读取所以集合中的元素,需要根据不同集合的特性定义不同的元素读取方法,这些方法被封装在了集合的内部类中。当我们需要调用集合的元素时,只需利用内部类对象来调用这些方法即可,而Collection接口为所以继承自Collection接口的集合提供了一个获取内部类对象的方法:iterator()。

ar1.iterator()——获取集合ar1的迭代器。

iterator()特性:该方法返回了迭代器(Iterator<E>接口)的对象,Iterator<E>接口中声明了三个方法:

  • boolean hasNext()——判断集合中是否仍有元素可以迭代,是返回true,否则返回false;

ar1.hasNext()——判断集合ar1中是否仍有元素和迭代。

  • E next()——返回迭代的下一个元素,即集合的下一个元素;

ar1.next()——返回ar1迭代的下一个元素。

  • Void remove()——从迭代器指向的collection中移除迭代器返回的最后一个元素(可操作)。

 

 

第四讲:List集合共性方法

List和Set都是Collection下的类,两者的区别如下:

  • List:元素是有序的,元素可以重复,因为该集合体系有索引
  • Set:元素是无序的,元素不可以重复

List特性:凡是可以操作角标的方法都是该体系特有的方法;

List方法:

1)  增

add(index,element)——在指定位置添加元素

addAll(index,Collection)——在指定位置添加元素集

2)  删

remove(index)——删除指定位置的元素

3)  改

Set(index,element)——将指定位置元素替换成element

4)  查

Get(index)——获取指定位置的元素;

subList(from,to)——获取指定位置区间的元素

listIterator()——利用迭代器获取元素

 

迭代器使用注意事项

在迭代过程中,对集合元素进行添加或删除操作时,不能同时使用迭代器和集合引用对集合元素进行添加或删除操作,如下代码会出现异常:

正确写法如下:

第五讲:ListIterator

概述:ListIterator是List集合特有的迭代器,是Iterator的子接口。

ListIterator的由来:在迭代时,同样不可以通过集合对象的方法操作集合中的元素,因为会发生ConcurrentModificationException异常。所以,在迭代时只能用迭代器的方式操作元素,可是Iterator中的方法是有限的,只能对集合中元素进行判断、取出、删除的操作,如果想要进行其他的操作,如,添加、修改等,就需要定义Iterator的子接口,并在该接口中增加需要的方法,该自接口为ListIterator。

获取方法:该接口只能通过List集合的listIterator()方法获取。使用实例如下:

 

第六讲:List集合具体对象的特点

ArrayList底层的数据结构使用的是数组结构,特点:查询速度快,但增删稍慢,线程不同步,但java中给出了便捷的解决方案;

LinkedList底层使用的是链表数据结构,特点:增删速度很快,但查询稍慢;

Vector底层是数组数据结构,线程同步,已经被ArrayList替代。

 

第七讲:Vector中的枚举

Vector有一个特殊的取出元素方法:枚举法Enumeration

枚举法和迭代器很像,他们的功能是重复的。

因为枚举法的名称以及方法名称都过长,所以就被后来的迭代器给取代了。枚举法读取元素方法如下:

第八讲:LinkedList

1、LinkedList的特有方法:

添加:addFirst()、addLast()

获取:getFirst()、getLast()——获取元素,但不删除元素。如果集合中没有元素,会出现NoSuchElementException异常

删除:removeFirst()、removeLast()——获取元素,但元素被删除。如果集合中没有元素,会出现NoSuchElementException异常

 

2、JDK1.6出现替代方法,可以避免因集合中没有元素出现的异常

添加:offerFirst()、offerLast()

获取:peekFirst()、peekLast()——获取元素,但元素不被删除。如果集合中没有元素,会返回null,不会抛出异常;

删除:pollFirst()、peekLast ()——获取元素,但元素被删除。如果集合中没有元素,会返回null,不会抛出异常;

 

练习:使用LinkedList模拟一个堆栈或者队列数据结构

堆栈:先进后出,如同一个杯子

队列:先进先出,如同一个水管

思路:利用LinkedList数据结构特性,封装一个符合自己要求的数据结构,这个数据结构向外提供添加、获取、删除等操作。

 

练习一:去除ArrayList集合中的重复元素

思路:创建一个新的集合,从老集合中读取元素并添加到新集合中,并将新集合地址赋给老集合,在添加之前先判断新集合中是否已经有此元素,若有,则不添加;否则添加。

练习二:将自定义对象作为元素存到ArrayList集合中,并去除重复元素

1、思路:

1)描述一个对象,将数据封装进这个对象中,以人为例;

2)定义一个容器,将人存入;

3)去除重复的人——姓名、年龄都相同的为同一个人;

         2、实现如下:

                 

         3、注意事项:

                   1)集合中remove(Object obj)方法的实现原理是:遍历集合,查找要删除的对象,过程需要调用equals方法进行判断集合中是否存在要删除的元素,因此,需要根据实际的情况重写equals。

                   2)集合中contains(Object obj)方法的实现原理:遍历集合,调用equals方法进行判断,集合中的元素是否存在和obj相同的元素,因此,需要根据实际的情况重写equals。

 

 

12  HashSet

Set元素是无序的(存入和取出的顺序不一定一致),元素不可以重复。在添加元素时,判断集合中是否已经存在与此对象地址一致的,若存在,则比较他们的值是否一致,若一致,则不添加此元素;若不一致,则在同地址值下面添加新对象。

Set集合的功能和Collection是一致的。

1、 HashSet

底层数据结构是哈希表。HashSet保证元素唯一性的方法如下:

通过元素的两个方法,hashCode和equals来完成。如果元素的HashCode值相同,才会判断equals是否为true;如果元素的HashCode值不同,不会调用equals。

所以在自定义对象的时候,通常需要重写hashCode和equals方法,重写示例如下:

注意:对于判断元素是否存在,以及操作,HashSet依赖的方法是元素的hashCode和equals;ArrayList依赖的只有equals。

 

小知识点总结

1、集合都有对集合中元素进行增、删、改、查的方法,不同的集合子类还有各自不同的操作方法。如List的特有方法有:add(index,element)、remove(index)、Set(index,element)、Get(index)等。

2、迭代器

迭代器就像一个连接集合和外部的工具,用于外部读取集合内部的元素。

它将读取元素的具体细节动作封装在集合内部,而给外部提供了共性的操作,即,获取迭代器对象、调用方法读取集合中的元素。

3、读取集合中元素的方法有三种:

1)利用remove()方法遍历集合中的元素

2)利用迭代器读取元素

3)利用枚举法读取集合中的元素——仅限于Vector

4、使用ArrayList或LinkedList的情景判断

当应用中需要频繁查询元素,但较少增删元素时,建议使用ArrayList;当需要频繁增删操作,但较少查询元素时,建议使用LinkedList;当既要频繁查询又要增删元素时,建议使用ArrayList。

5、自定义数据结构

我们可以利用已有的数据结构来自定义自己需要的数据结构,自定义该数据结构的方法,以此来限制或扩展数据结构的特性。如自定义该数据结构的增、删、改、查等功能。

 

 

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。