JavaSE - 集合类-工具类
本节学习目标:
- 了解和掌握迭代器的使用方法;
- 了解和掌握比较器的使用方法;
- 了解和掌握选择器的使用方法;
- 了解和掌握Collections工具类中的常用方法。
1. 集合工具接口
Java对集合框架提供了很多工具接口,我们可以实现或使用这些接口来对集合进行修改与定制化。
1.1 迭代器
1. Iterable 接口
Iterable
接口位于java.lang
包下,意为可遍历的。
Collection
接口继承了Iterable
接口,所以Collection集合是可以使用迭代器进行遍历。Iterable
接口提供的方法:
方法 | 返回值 | 功能 |
---|---|---|
iterator() | Iterator<T> | 获取当前集合的迭代器 |
2. Iterator 接口
Iterator
接口位于java.util
包下,实现Iterator
接口的类被称为迭代器,可以使用迭代器对Collection集合进行遍历等操作,Iterator
接口提供的方法:
方法 | 返回值 | 功能 |
---|---|---|
hasNext() | boolean | 返回游标的下一个位置是否存在元素 |
next() | E | 返回游标下一个位置的元素 |
remove() | void | 移除游标位置的元素 |
编写代码进行测试:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class TestIterator {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(57);
list.add(6);
list.add(-64);
Iterator<Integer> iterator1 = list.iterator();
while (iterator1.hasNext()) {
if (iterator1.next().equals(6)) {
iterator1.remove();
}
}
Iterator<Integer> iterator2 = list.iterator();
while (iterator2.hasNext()) {
System.out.print(iterator2.next() + " ");
}
}
}
// 运行结果
// 57 -64
迭代器的特性:
- 迭代器拥有一个游标,刚获取的迭代器的游标指向集合中第一个元素的前一个元素(
null
); - 调用
hasNext()
方法会检查游标指向位置的后一个位置是否存在元素,是返回true
,否返回false
,可用于循环的控制条件。 - 调用
next()
方法后游标会先向后移动一个元素,然后返回移动后游标位置的元素。如果游标已到达集合末尾(即hasNext()
方法返回false
),这时再调用next()
方法会抛出NoSuchElementException
异常; - 调用
remove()
方法后游标会移除当前位置的元素。如果此时还未调用next()
方法,或已经调用remove()
方法,这时游标指向的元素为null
。再次调用remove()
方法后会抛出IllegalStateException
异常; - 每次调用
iterator()
方法返回的是新的迭代器,与之前已经获取的迭代器独立,游标位置是初始位置。
Collection集合的除了可以使用迭代器进行遍历,还可以使用foreach循环语句(即增强for循环)进行遍历:
public class TestIterator {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(57);
list.add(6);
list.add(-64);
for (Integer i : list) {
System.out.println(i);
}
}
}
// 运行结果
// 57 6 -64
1.2 比较器
比较器在使用TreeSet和TreeMap集合的时候比较常用,可以将元素或键值对的键按照某一属性进行排序。
有两种排序方式:
- 自然排序:让元素或键值对的键实现
Comparable
接口并重写compareTo()
方法; - 定制排序:编写外部比较器,实现
Comparator
接口并重写compare()
方法。
1. Comparable 接口
Comparable
接口位于java.lang
包下,它被称为内部比较器,定义在需要排序的JavaBean类内部。它只有一个方法:
方法 | 返回值 | 功能 |
---|---|---|
compareTo(T o) | int | 内部比较方法,当前对象与参数对象进行比较 |
元素和键值对的键可以实现Comparable
接口,重写compareTo()
方法,以实现自然排序:
public class Person implements Comparable<Integer> {
private Integer age;
private String name;
@Override
public int compareTo(Integer o) {
if (o == null) {
throw new IllegalArgumentException();
}
// 对age进行排序
// 如果相等返回0
if (this.age.equals(o)) {
return 0;
// age从小到大排序
// 如果当前age比参数大返回一个正数(1)
} else if (this.age > o) {
return 1;
// 如果当前age比参数晓返回一个负数(-1)
} else {
return -1;
}
}
// 省略其他代码
}
编写代码进行测试:
import java.util.Set;
import java.util.TreeSet;
public class TestComparable {
public static void main(String[] args) {
Set<Person> set = new TreeSet<>();
set.add(new Person().setAge(32).setName("张三"));
set.add(new Person().setAge(24).setName("李四"));
set.add(new Person().setAge(35).setName("王五"));
set.add(new Person().setAge(18).setName("赵六"));
for (Person p : set) {
System.out.println(p);
}
}
}
/* 运行结果
Person{age=18, name='赵六'}
Person{age=24, name='李四'}
Person{age=32, name='张三'}
Person{age=35, name='王五'}
*/
2. Comparator 接口
Comparator
接口位于java.util
包下,它被称为外部比较器,定义在JavaBean类的外部,是独立的类(大多数使用内部类形式)。
它被@FunctionalInterface
注解标注,所以可以使用lambda表达式实现。它的主要方法:
方法 | 返回值 | 功能 |
---|---|---|
compare(T o1, T o2) | int | 外部比较方法,对象o1和对象o2进行比较 |
外部比较器实现Comparator
接口,并重写compare()
方法,然后让集合使用,以实现定制排序:
public class TestComparable {
public static void main(String[] args) {
// 使用内部类编写外部比较器
// lambda表达式写法:
// Comparator<Person> comparator = (o1, o2) -> {
// if (o1 == null || o2 == null) {
// throw new IllegalArgumentException();
// }
// if (o1.getAge().equals(o2.getAge())) {
// return 0;
// } else if (o1.getAge() > o2.getAge()) {
// return -1;
// } else {
// return 1;
// }
// };
Comparator<Person> comparator = new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
if (o1 == null || o2 == null) {
throw new IllegalArgumentException();
}
// 对age进行排序
// 如果相等返回0
if (o1.getAge().equals(o2.getAge())) {
return 0;
// age从大到小排序
// 如果o1的age比o2大返回一个负数(-1)
} else if (o1.getAge() > o2.getAge()) {
return -1;
// 如果o1的age比o2小返回一个正数(1)
} else {
return 1;
}
}
};
// 使用集合的有参构造方法,传入比较器进行定制排序
Set<Person> set = new TreeSet<>(comparator);
set.add(new Person().setAge(32).setName("张三"));
set.add(new Person().setAge(24).setName("李四"));
set.add(new Person().setAge(35).setName("王五"));
set.add(new Person().setAge(18).setName("赵六"));
for (Person p : set) {
System.out.println(p);
}
}
}
/* 运行结果
Person{age=35, name='王五'}
Person{age=32, name='张三'}
Person{age=24, name='李四'}
Person{age=18, name='赵六'}
*/
1.3 过滤器(Predicate 接口)
Predicate
接口位于java.util.function
包下,它可以用来以某个条件筛选集合中的数据,所以被称为过滤器。
它被@FunctionalInterface
注解标注,因此可以使用lambda表达式实现。它的主要方法:
方法 | 返回值 | 功能 |
---|---|---|
test(T t) | boolean | 测试方法,如果返回true 则符合条件,返回false 不符合条件 |
使用1.2节的Person
类,编写代码进行测试:
public class TestPredicate {
public static void main(String[] args) {
// 过滤器
// lambda表达式写法:
// Predicate<Person> filter = person -> {
// return person.getAge() > 30;
// };
Predicate<Person> filter = new Predicate<Person>() {
@Override
public boolean test(Person person) {
// 筛选age大于30的person对象
return person.getAge() > 30;
}
};
Set<Person> set = new TreeSet<>();
set.add(new Person().setAge(32).setName("张三"));
set.add(new Person().setAge(24).setName("李四"));
set.add(new Person().setAge(35).setName("王五"));
set.add(new Person().setAge(18).setName("赵六"));
// 移除符合过滤器条件的person对象
set.removeIf(filter);
for (Person p : set) {
System.out.println(p);
}
}
}
/* 运行结果
Person{age=18, name='赵六'}
Person{age=24, name='李四'}
*/
2. Collections 工具类
Collections
工具类位于java.util
包下,它提供了大量静态方法用于对Collection集合以及Map集合的各种操作。
2.1 查询方法
Collections工具类提供的查询方法:
方法 | 返回值 | 功能 |
---|---|---|
max(Collection<? extends T> coll) | T | 以自然排序方式返回Collection集合coll 中的最大元素 |
max(Collection<? extends T> coll, Comparator<? super T> comp) | T | 传入比较器comp 以定制排序方式返回Collection集合 coll 中的最大元素 |
min(Collection<? extends T> coll) | T | 以自然排序方式返回Collection集合coll 中的最小元素 |
min(Collection<? extends T> coll, Comparator<? super T> comp) | T | 传入比较器comp 以定制排序方式返回Collection集合 coll 中的最小元素 |
frequency(Collection<?> c, Object o) | int | 返回元素o 在Collection集合c 中出现的次数 |
2.2 操作方法
Collections工具类提供的操作方法:
方法 | 返回值 | 功能 |
---|---|---|
addAll(Collection<? super T> c, T... elements) | boolean | 向Collection集合c 中添加元素,可以添加多个元素 |
copy(List<? super T> dest, List<? extends T> src) | void | 将List集合src 中的元素复制至List集合desc 中,复制后元素的索引不变, desc 长度至少与src 长度相同 |
fill(List<? super T> list, T obj) | void | 将obj 填充到List集合list 中 |
replaceAll(List<T> list, T oldVal, T newVal) | boolean | 将List集合list 中所有元素oldVal 替换为元素newVal |
swap(List<?> list, int i, int j) | void | 将List集合list 中索引为i 和j 位置的元素交换 |
2.3 排序方法
Collections工具类提供的排序方法:
方法 | 返回值 | 功能 |
---|---|---|
reverse(List<?> list) | void | 将List集合list 中的元素反转为倒序 |
shuffle(List<?> list) | void | 将List集合list 中的元素进行随机排序 |
shuffle(List<?> list, Random rnd) | void | 使用指定随机数产生器rnd 对List集合list 中的元素进行随机排序 |
sort(List<T> list) | void | 按照元素的某一属性对List集合list 中的元素进行自然排序 |
sort(List<T> list, Comparator<? super T> c) | void | 传入比较器c 对List集合list 中的元素进行定制排序 |
2.4 单例集合方法
这些方法会返回一个只有一个元素的不可变集合,并且长度只有1
,可节省内存空间:
方法 | 返回值 | 功能 |
---|---|---|
singleton(T o) | Set<T> | 返回一个只有元素o 的不可变Set集合 |
singletonList(T o) | List<T> | 返回一个只有元素o 的不可变List集合 |
singletonMap(K key, V value) | Map<K,V> | 返回一个只有一个键值对的不可变Map集合, 键值对的键为 key ,键值对的值为value |
2.5 空集合方法
这些方法会返回一个空的不可变集合,可节省内存空间:
方法 | 返回值 | 功能 |
---|---|---|
emptyList() | List<T> | 返回一个不可变的空List集合 |
emptySet() | Set<T> | 返回一个不可变的空Set集合 |
emptyMap() | Map<K,V> | 返回一个不可变的空Map集合 |
2.6 同步集合方法
这些方法将传入的集合包装为线程安全的集合,以适用于多线程环境:
方法 | 返回值 | 功能 |
---|---|---|
synchronizedList(List<T> list) | List<T> | 将List集合list 包装为线程安全的List集合 |
synchronizedSet(Set<T> s) | Set<T> | 将Set集合s 包装为线程安全的Set集合 |
synchronizedSortedSet(SortedSet<T> s) | SortedSet<T> | 将SortedSet集合s 包装为线程安全的SortedSet集合 |
synchronizedNavigableSet(NavigableSet<T> s) | NavigableSet<T> s) | 将NavigableSet集合s 包装为线程安全的NavigableSet集合 |
synchronizedMap(Map<K,V> m) | Map<K,V> | 将Map集合m 包装为线程安全的Map集合 |
synchronizedSortedMap(SortedMap<K,V> m) | SortedMap<K,V> | 将SortedMap集合m 包装为线程安全的SortedMap集合 |
synchronizedNavigableMap(NavigableMap<K,V> m) | NavigableMap<K,V> | 将NavigableMap集合m 包装为线程安全的NavigableMap集合 |