目录
一、List
- 特点:有序、有索引、可以重复元素。
- 实现类:ArrayList、LinkList。
- 遍历方式:迭代器、普通For循环、增强For循环
- 常用方法:
带索引 ,所以一定要注意访问越界。
- 迭代器的并发修改异常
发生ConcurrentMdificationException异常。在迭代过程中,使用了集合的方法对元素进行操作。导致迭代器并不知道集合中的变化(比如说插入一个元素,导致集合长度发生改变),容易引发数据的不确定性。
并发修改异常解决办法:在迭代时,不要使用集合的方法操作元素。
那么想要在迭代时对元素操作咋办?通过ListIterator迭代器操作元素是可以的,ListIterator的出现,解决了使用Iterator迭代过程中可能会发生的错误情况。
- List集合存储数据的结构
ArrayList集合:数据存储的结构是数组结构。元素增删慢,查找快。
LinkedList集合:数据存储的结构是链表结构。方便元素添加、删除的集合。
- Vector:线程安全、运行速度慢。已经被抛弃。
二、set&HashSet
- 特点:无序、无索引、无重复元素、允许有null。
- Set接口介绍:查阅Set集合的API介绍,通过元素的equals方法,来判断是否为重复元素。
HashSet
- 介绍
查阅HashSet集合的API介绍:此类实现Set接口,由哈希表支持(实际上是一个 HashMap集合)。HashSet集合不能保证的迭代顺序与元素存储顺序相同。(HashSet底层由HashMap实现)
HashSet集合,采用哈希表结构存储数据,保证元素唯一性的方式依赖于:hashCode()与equals()方法。
-
遍历方法:迭代器、增强For。
-
HashSet集合元素的唯一性实现原理:先调用hashcode()比较哈希码值,如果不同直接存,如果相同再调用equal()比较成员变量值。
给HashSet中存储JavaAPI中提供的类型元素时,不需要重写元素的hashCode和equals方法,因为这两个方法,在JavaAPI的每个类中已经重写完毕,如String类、Integer类等。而自己定义数据类型(比如 new Person())则需要重写这两个方法(可以使用编译器快捷键自动添加)。
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if(!(obj instanceof Student)){
System.out.println("类型错误");
return false;
}
Student other = (Student) obj;
return this.age == other.age && this.name.equals(other.name);
}
- LinkedHashSet
LinkedHashSet继承自HashSet,其自身特点是:有序(存和取得顺序一样);用双重链表来实现。
三、判断集合元素唯一性原理
- ArrayList的contains方法判断元素是否重复原理
ArrayList的contains方法会使用调用方法时,传入的元素的equals方法依次与集合中的旧元素所比较,从而根据返回的布尔值判断是否有重复元素。此时,当ArrayList存放自定义类型时,由于自定义类型在未重写equals方法前,判断是否重复的依据是地址值,所以如果想根据内容判断是否为重复元素,需要重写元素的equals方法。
- HashSet的add/contains等方法判断元素是否重复原理
Set集合不能存放重复元素,其添加方法在添加时会判断是否有重复元素,有重复不添加,没重复则添加。
HashSet集合由于是无序的,其判断唯一的依据是元素类型的hashCode与equals方法的返回结果。规则如下:
先判断新元素与集合内已经有的旧元素的HashCode值
如果不同,说明是不同元素,添加到集合。
如果相同,再判断equals比较结果。返回true则相同元素;返回false则不同元素,添加到集合。
所以,使用HashSet存储自定义类型,如果没有重写该类的hashCode与equals方法,则判断重复时,使用的是地址值, 如果想通过内容比较元素是否相同,需要重写该元素类的hashcode与equals方法。
四、总结
- List与Set集合的区别?
List:
它是一个有序的集合(元素存与取的顺序相同)
它可以存储重复的元素
Set:
它是一个无序的集合(元素存与取的顺序可能不同)
它不能存储重复的元素
- List集合中的特有方法
- void add(int index, Object element) 将指定的元素,添加到该集合中的指定位置上
- Object get(int index)返回集合中指定位置的元素。
- Object remove(int index) 移除列表中指定位置的元素, 返回的是被移除的元素
- Object set(int index, Object element)用指定元素替换集合中指定位置的元素,返回值的更新前的元素
- ArrayList:
底层数据结构是数组,查询快,增删慢
- LinkedList:
底层数据结构是链表,查询慢,增删快
- HashSet:
元素唯一,不能重复
底层结构是 哈希表结构
元素的存与取的顺序不能保证一致
如何保证元素的唯一的?
重写hashCode() 与 equals()方法
- LinkedHashSet:
元素唯一不能重复
底层结构是 哈希表结构 + 链表结构
元素的存与取的顺序一致