JavaSE - 集合类-工具类

Posted adas5f1a51

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaSE - 集合类-工具类相关的知识,希望对你有一定的参考价值。

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);
        
    


/* 运行结果
Personage=18, name='赵六'
Personage=24, name='李四'
Personage=32, name='张三'
Personage=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);
        
    


/* 运行结果
Personage=35, name='王五'
Personage=32, name='张三'
Personage=24, name='李四'
Personage=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);
        
    


/* 运行结果
Personage=18, name='赵六'
Personage=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)voidobj填充到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中索引为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<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集合

以上是关于JavaSE - 集合类-工具类的主要内容,如果未能解决你的问题,请参考以下文章

JavaSE——可变参数&集合工具类

JavaSE集合基础总览

JavaSE大纲

JavaSE——数组集合

JavaSE复习总结之集合(Collection)

JavaSE高级之集合类