JavaSE - 集合类-工具类

JavaSE - 集合类-工具类

本节学习目标:

  • 了解和掌握迭代器的使用方法;
  • 了解和掌握比较器的使用方法;
  • 了解和掌握选择器的使用方法;
  • 了解和掌握Collections工具类中的常用方法。

1. 集合工具接口

Java对集合框架提供了很多工具接口,我们可以实现或使用这些接口来对集合进行修改与定制化。

1.1 迭代器

1. Iterable 接口

Iterable接口位于java.lang包下,意为可遍历的

Collection接口继承了Iterable接口,所以Collection集合是可以使用迭代器进行遍历。Iterable接口提供的方法:

方法 返回值 功能
iterator() Iterator 获取当前集合的迭代器

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 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 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 coll) T 自然排序方式返回Collection集合coll中的最大元素
max(Collection coll, Comparator comp) T 传入比较器comp定制排序方式
返回Collection集合coll中的最大元素
min(Collection coll) T 自然排序方式返回Collection集合coll中的最小元素
min(Collection coll, Comparator comp) T 传入比较器comp定制排序方式
返回Collection集合coll中的最小元素
frequency(Collection c, Object o) int 返回元素o在Collection集合c出现的次数

2.2 操作方法

Collections工具类提供的操作方法:

方法 返回值 功能
addAll(Collection c, T... elements) boolean 向Collection集合c添加元素,可以添加多个元素
copy(List dest, List src) void 将List集合src中的元素复制至List集合desc中,
复制后元素的索引不变desc长度至少与src长度相同
fill(List list, T obj) void obj填充到List集合list
replaceAll(List list, T oldVal, T newVal) boolean 将List集合list中所有元素oldVal替换为元素newVal
swap(List list, int i, int j) void 将List集合list中索引为ij位置的元素交换

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 list) void 按照元素的某一属性对List集合list中的元素进行自然排序
sort(List list, Comparator c) void 传入比较器c对List集合list中的元素进行定制排序

2.4 单例集合方法

这些方法会返回一个只有一个元素不可变集合,并且长度只有1,可节省内存空间:

方法 返回值 功能
singleton(T o) Set 返回一个只有元素o不可变Set集合
singletonList(T o) List 返回一个只有元素o不可变List集合
singletonMap(K key, V value) Map 返回一个只有一个键值对的不可变Map集合,
键值对的key,键值对的value

2.5 空集合方法

这些方法会返回一个空的不可变集合,可节省内存空间:

方法 返回值 功能
emptyList() List 返回一个不可变List集合
emptySet() Set 返回一个不可变Set集合
emptyMap() Map 返回一个不可变Map集合

2.6 同步集合方法

这些方法将传入的集合包装为线程安全的集合,以适用于多线程环境:

方法 返回值 功能
synchronizedList(List list) List 将List集合list包装为线程安全的List集合
synchronizedSet(Set s) Set 将Set集合s包装为线程安全的Set集合
synchronizedSortedSet(SortedSet s) SortedSet 将SortedSet集合s包装为
线程安全的SortedSet集合
synchronizedNavigableSet(NavigableSet s) NavigableSet s) 将NavigableSet集合s包装为线程安全的NavigableSet集合
synchronizedMap(Map m) Map 将Map集合m包装为线程安全的Map集合
synchronizedSortedMap(SortedMap m) SortedMap 将SortedMap集合m包装为线程安全的SortedMap集合
synchronizedNavigableMap(NavigableMap m) NavigableMap 将NavigableMap集合m包装为
线程安全的NavigableMap集合

你可能感兴趣的:(我的Java基础学习之路,java,javase,面试,集合,工具类)