Collection
Collection接口并不直接创建实例,而是由其子接口(如List、Set、Queue等)和实现类(如ArrayList、HashSet、LinkedList等)提供具体的实现。
常用方法
方法 | 作用 |
---|---|
add(obj) | 添加单个元素到集合中 |
addAll(Collection col) | 添加 B集合到 A集合中(集合合并) |
clear() | 清空集合 |
remove(obj) / remove(index) | 移除指定元素 |
contains(obj) | 判断集合是否包含指定元素 |
isEmpty() | 判断集合是否为空 |
size() | 获取集合元素数量 |
toArray() | 把集合转换为数组 |
java
@Test
public void junitTest() {
Collection<String> collection = new ArrayList<>();
collection.add("张三");
collection.add("李四");
Collection<String> collection1 = new ArrayList<>();
collection1.add("Tom");
collection1.add("Sunny");
//将 collection1 集合与 collection 合并
collection.addAll(collection1);
System.out.println(collection); //[张三, 李四, Tom, Sunny]
}
java
@Test
public void junitTest1() {
Collection<String> collection = new ArrayList<>();
collection.add("张三");
collection.add("李四");
collection.add("王五");
collection.remove("李四");
System.out.println(collection); //[张三, 王五]
collection.clear();
System.out.println(collection); //[]
}
java
@Test
public void junitTest2() {
Collection<String> collection = new ArrayList<>();
collection.add("张三");
collection.add("李四");
collection.add("王五");
boolean empty = collection.isEmpty();
System.out.println(empty); //false
boolean isContain = collection.contains("王五");
System.out.println(isContain); //true
}
java
@Test
public void junitTest3() {
Collection<String> collection = new ArrayList<>();
collection.add("张三");
collection.add("李四");
collection.add("王五");
int size = collection.size();
System.out.println(size); //3
Object[] array = collection.toArray();
System.out.println(Arrays.toString(array)); //[张三, 李四, 王五]
}
注意
add() 方法如果添加 B集合到 A集合中,也能添加,但是会把 B集合当作一个整体添加到 A集合中。
java
@Test
public void junitTest() {
//不写 <E> 默认是 Object
Collection collection = new ArrayList();
collection.add(100);
collection.add(true);
Collection collection1 = new ArrayList();
collection1.add("hello");
collection1.add("world");
collection.add(collection1);
System.out.println(collection); //[100, true, [hello, world]]
}
迭代器
迭代器(Iterator)提供了一种 顺序访问集合元素 的方式,而不需要了解集合的底层实现细节。
java
@Test
public void junitTest4() {
ArrayList<String> arrayList = new ArrayList<String>();
arrayList.add("张三");
arrayList.add("李四");
arrayList.add("王五");
Iterator<String> iterator = arrayList.iterator();
while (iterator.hasNext()) {
String element = iterator.next();
System.out.println(element);
}
}
注意
使用 iterator()
迭代集合时,next() 方法不要同时使用 2 次,否则会报 NoSuchElementException 错。
java
@Test
public void junitTest4() {
ArrayList<String> arrayList = new ArrayList<String>();
arrayList.add("张三");
arrayList.add("李四");
arrayList.add("王五");
arrayList.add("赵六");
arrayList.add("王一博");
Iterator<String> iterator = arrayList.iterator();
while (iterator.hasNext()) {
String element = iterator.next();
System.out.println(element);
//如果是集合是偶数个元素,不会报错,奇数个元素时,next()获取不到元素了,就会报错
String element1 = iterator.next();
System.out.println(element1);
}
}
并发修改异常
当使用 迭代器/增强For 遍历集合的过程中,尽量不要随意修改集合的内容,例如增加、删除等!
下面的示例,就会引发并发修改异常:
java
@Test
public void junitTest5() {
ArrayList<String> arrayList = new ArrayList<String>();
arrayList.add("张三");
arrayList.add("李四");
arrayList.add("王五");
Iterator<String> iterator = arrayList.iterator();
while (iterator.hasNext()) {
String element = iterator.next(); //报错
if ("李四".equals(element)) {
arrayList.add("陈伟霆");
}
System.out.println(element);
}
}
问题出在 iterator.next() 方法的调用上,内部使用了 checkForComodification() 函数来判断当前集合的 预期迭代次数和实际迭代次数是否相同,不相同时就会报并发修改异常。
其实,本质是 add() 方法添加新元素时,没有修改实际迭代次数,导致二者不相同下一次 iterator.next() 就会报错。
解决方法:
java
@Test
public void junitTest5() {
ArrayList<String> arrayList = new ArrayList<String>();
arrayList.add("张三");
arrayList.add("李四");
arrayList.add("王五");
//使用 ArrayList 父类中的 listIterator() 迭代器进行遍历
ListIterator<String> listIterator = arrayList.listIterator();
while (listIterator.hasNext()) {
String element = listIterator.next();
if ("李四".equals(element)) {
listIterator.add("陈伟霆");
}
}
System.out.println(arrayList); //[张三, 李四, 陈伟霆, 王五]
}
扩展方法
方法 | 作用 |
---|---|
addAll(Collection c, T... ele) | 向集合批量添加元素 |
shuffle(list) | 将集合中的元素顺序打乱 |
sort(list) | 将集合中的元素进行排序(默认使用 ASCII 码值) |
sort(List list, Comparator c) | 将集合中的元素按自定义的排序方式排序 |
java
@Test
public void junitTest() {
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "Apple", "Banana", "Orange");
//打乱排序,每次运行顺序都不一样
Collections.shuffle(list);
}
java
@Test
public void junitTest1() {
ArrayList<String> list = new ArrayList<>();
list.add("d.低头思故乡");
list.add("a.窗前明月光");
list.add("c.举头望明月");
list.add("b.疑是地上霜");
//默认使用 ASCII 码排序,如果第一个值相同,则按第二个比较
Collections.sort(list);
}
java
@Test
public void junitTest2() {
ArrayList<Person> people = new ArrayList<>();
people.add(new Person("王一博", 23));
people.add(new Person("陈伟霆", 34));
people.add(new Person("彭于晏", 32));
people.add(new Person("Sunny", 18));
Collections.sort(people, new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
return o1.getAge() - o2.getAge(); //升序
//return o2.getAge() - o1.getAge(); //降序
}
});
System.out.println(people);
}
java
@Test
public void junitTest3() {
ArrayList<Student> students = new ArrayList<>();
students.add(new Student("王一博", 23));
students.add(new Student("陈伟霆", 34));
students.add(new Student("彭于晏", 32));
students.add(new Student("Sunny", 18));
Collections.sort(students);
System.out.println(students);
}
java
public class Student implements Comparable<Student> {
private String name;
private Integer age;
public Student() {
}
public Student(String name, Integer age) {
this.name = name;
this.age = age;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(Student o) {
return this.getAge() - o.getAge();
}
}