当前位置:首页 » 《随便一记》 » 正文

JavaSE

20 人参与  2022年05月27日 11:26  分类 : 《随便一记》  评论

点击全文阅读


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)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集合

点击全文阅读


本文链接:http://zhangshiyu.com/post/40845.html

集合  方法  元素  
<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1