原文 http://www.jianshu.com/p/2070cb32accb
List接口
查阅API,看 List
的介绍。有序的 collection
(也称为序列)。此接口的用户可以对列表中每个元素的插入位置进行精确地控制。用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。与 set
不同,列表通常允许重复的元素
特点:
- 它是一个元素储存有序的集合
- 它是一个带有索引的集合
- 集合中可以有重复的元素
常用的子类:
-
ArrayList
集合 -
LinkedList
集合
常用方法

image.png
方法演示
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List; public class Test {
public static void main(String[] args){
List<String> list = new ArrayList<String>(); // 添加元素
list.add("cuzz");
list.add("uzi");
list.add("faker");
System.out.println(list); // [cuzz, uzi, faker] // 指定位置添加元素
list.add(1, "mlxg");
System.out.println(list); // [cuzz, mlxg, uzi, faker] // 删除元素
list.remove(2);
System.out.println(list); // [cuzz, mlxg, faker] boolean a = list.remove("cuzz"); // true
System.out.println(a);
System.out.println(list); // [mlxg, faker] // 修改元素
list.set(1, "FAKER");
System.out.println(list); // [mlxg, FAKER] // 迭代
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()){
String str = iterator.next();
System.out.println(str);
} // 由于List有索引,除了使用迭代器的方法,还可以使用索引的方式
for (int i = 0; i < list.size(); i++){
String str = list.get(i);
System.out.println(str);
}
}
}
Iterator的并发修改的异常
在list集合迭代元素中,对元素进行判断,一旦条件满足就添加一个新元素
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List; public class Test1 {
public static void main(String[] args) {
// 创建List集合
List<String> list = new ArrayList<String>();
// 给集合中添加元素
list.add("abc1");
list.add("abc2");
list.add("abc3");
list.add("abc4"); // 迭代集合,当有元素为"abc2"时,集合加入新元素"ABC2"
Iterator<String> iterator = list.iterator();
while(iterator.hasNext()){
String str = iterator.next();
// 判断取出的元素是否是"abc2",是就添加一个新元素
if("abc2".equals(str)){
list.add("ABC2"); // 该操作会导致程序出错
}
}
// 打印容器中的元素
System.out.println(list);
}
}
当我们在遍历实现了 collection
接口与 iterator
接口的集合时( List
、 Set
、 Map
), 我们可以通过遍历索引也可以通过迭代器进行遍历。
在我们使用迭代器进行遍历集合的时候,会获取到当前集合的迭代对象。在里面有封装了迭代器 iterator.remove()
方法与集合自带的 list.remove()
方法
如果我们调用迭代器象的 remove()
方法是没问题的,但是当我们调用集合自带的 remove()
方法时,就会产生 ConcurrentModificationException
并发修改异常。也就是说,当我们通过迭代器进行遍历集合的时候,是不允许集合本身在结构上发生变化的
解决办法
ListIterator
可以再迭代时对集合进行 add
、 set
、 remove
操作,而 Iterator
迭代器只能在迭代时对集合进行 remove
操作
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator; public class Test1 {
public static void main(String[] args) {
// 创建List集合
List<String> list = new ArrayList<String>();
// 给集合中添加元素
list.add("abc1");
list.add("abc2");
list.add("abc3");
list.add("abc4"); // 迭代集合,当有元素为"abc2"时,集合加入新元素"ABC2"
ListIterator<String> listIterator = list.listIterator();
while(listIterator.hasNext()){
String str = listIterator.next();
//判断取出的元素是否是"abc2",是就添加一个新元素
if("abc2".equals(str)){
// 使用迭代器封装的add
listIterator.add("ABC2");
}
}
// 打印容器中的元素
System.out.println(list); // [abc1, abc2, ABC2, abc3, abc4]
}
}
ArrayList集合
ArrayList
集合数据存储的结构是数组结构。元素增删慢,查找快,由于日常开发中使用最多的功能为查询数据、遍历数据,所以 ArrayList
是最常用的集合
LinkedList集合
LinkedList
集合数据存储的结构是链表结构。方便元素添加、删除的集合。实际开发中对一个集合元素的添加与删除经常涉及到首尾操作,而 LinkedList
提供了大量首尾操作的方法

image.png
Set接口
Set
继承于 Collectio
n接口,是一个不允许出现重复元素,并且无序的集合,主要有 HashSet
、 LinkedHashSet
和 TreeSet
在判断重复元素的时候, Set
集合会调用 hashCode()
和 equals()
方法来实现
HashSet
import java.util.HashSet; public class Test2 {
public static void main(String[] args) {
// 创建HashSetd对象
HashSet<String> hashSet = new HashSet<String>(); // 添加对象
hashSet.add("cuzz");
hashSet.add("uzi");
hashSet.add("faker");
hashSet.add("cuzz"); System.out.println(hashSet); // [uzi, cuzz, faker]
}
}
HashSet储存自定义类型的元素
保证 HashSet
集合元素的唯一,其实就是根据对象的 hashCode()
和 equals()
方法来决定的。如果我们往集合中存放自定义的对象,那么保证其唯一,就必须复写 hashCode
()和 equals()
方法建立属于当前对象的比较方式
创建自定义 Student
对象
public class Student {
private String name;
private int age;
// 构造方法
public Student(String name, int age){
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
} // 重新toString
public String toString(){
return "Student [name:" + name + " " + "age=" + age + "]";
} // 重写hashCode
public int hashCode(){
final int prime = 31;
int result = 1;
result = prime*result + age;
result = prime*result + ((name == null) ? 0 :name.hashCode());
return result;
} // 重写equals
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);
}
}
创建 HashSet
集合,存储 Student
对象
import java.util.HashSet; public class HashSetDemo {
public static void main(String[] args) {
// 创建HashSetd对象
HashSet<Student> hashSet = new HashSet<Student>(); // 添加对象
hashSet.add(new Student("cuzz",20));
hashSet.add(new Student("uzi", 21));
hashSet.add(new Student("faker", 22));
hashSet.add(new Student("cuzz", 20)); System.out.println(hashSet); // Student [name:faker age=22],
// Student [name:cuzz age=20],
// Student [name:uzi age=21]]
}
}
LinkedHashSet
LinkedHashSet
它是链表和哈希表组合的一个数据存储结构,可以保证元素存放时有顺序的