JDK Collections工具类

起因:工作中需要对集合进行一个乱序的重排序,当时不太记得Collections中的方法,去百度了一下,发现Collections工具类提供了相应的方法,之前有用过Collections其中的一些方法,但是没有对其API有一个系统的学习和记录,这次记录一下。知道这里有了,用的时候也好找了。

Collections是 JDK提供的工具类,提供了一系列静态方法,方便操作各种集合。分析和总结一下其API,记录一下。

Collections主要有以下几个功能

  • 排序
  • 乱序(洗牌)
  • 替换
  • 创建空集合
  • 创建单元集合
  • 不可变集合
  • 线程安全集合

接下来稍微介绍一下相关操作与demo,其实看api更好。

1.排序

  • reverse(List list):反转指定List集合中元素的顺序
  • shuffle(List list):对List中的元素进行随机排序(洗牌)
  • sort(List list):对List里的元素根据自然升序排序
  • sort(List list, Comparator c):自定义比较器进行排序
  • swap(List list, int i, int j):将指定List集合中i处元素和j出元素进行交换
  • rotate(List list, int distance):将所有元素向右移位指定长度,如果distance等于size那么结果不变

Collections可以对List进行sort排序。因为排序会直接修改List元素的位置,因此必须传入可变List。

    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("apple");
        list.add("pear");
        list.add("orange");
        // 排序前:
        System.out.println(list);
        Collections.sort(list);
        // 排序后:
        System.out.println(list);
    }

排序也是有讲究的。列表中的所有元素必须实现Comparable接口,因为最终还是要根据Comparable中的方法来对其实施排序。以下是JDK源码。
除了默认排序还有自定义排序,自定义排序需要传入Comparator比较器。一般使用compare(T o1, T o2)方法就可以了,比较常用的还有reversed()方法,到排序。详情见我的另一篇,排序!

//默认排序    
    public static <T extends Comparable<? super T>> void sort(List<T> list) {
        list.sort(null);
    }
//自定义排序
    public static <T> void sort(List<T> list, Comparator<? super T> c) {
        list.sort(c);
    }

2.乱序(洗牌)

Collections提供了洗牌算法,即传入一个有序的List,可以随机打乱List内部元素的顺序,效果相当于让计算机洗牌:

    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        for (int i=0; i<10; i++) {
            list.add(i);
        }
        // 洗牌前:
        System.out.println(list);
        Collections.shuffle(list);
        // 洗牌后:
        System.out.println(list);
    }

排序其实就是拿到传入的list,然后对任意两个元素交换位置,也可以传入一个带随机数的,没看源码,有空可以了解一下。

    public static void shuffle(List<?> list) {
        Random rnd = r;
        if (rnd == null)
            r = rnd = new Random(); // harmless race.
        shuffle(list, rnd);
    }

    private static Random r;
//--------------------------------------
    public static void shuffle(List<?> list, Random rnd) {
        int size = list.size();
        if (size < SHUFFLE_THRESHOLD || list instanceof RandomAccess) {
            for (int i=size; i>1; i--)
                swap(list, i-1, rnd.nextInt(i));
        } else {
            Object arr[] = list.toArray();

            // Shuffle array
            for (int i=size; i>1; i--)
                swap(arr, i-1, rnd.nextInt(i));

            // Dump array back into list
            // instead of using a raw type here, it's possible to capture
            // the wildcard but it will require a call to a supplementary
            // private method
            ListIterator it = list.listIterator();
            for (int i=0; i<arr.length; i++) {
                it.next();
                it.set(arr[i]);
            }
        }
    }
//--------------------------------------
    private static void swap(Object[] arr, int i, int j) {
        Object tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }

3. 查找和替换

  • binarySearch(List list, Object key):使用二分搜索法,以获得指定对象在List中的索引,前提是集合已经排序
  • max(Collection coll):返回最大元素
  • max(Collection coll, Comparator comp):根据自定义比较器,返回最大元素
  • min(Collection coll):返回最小元素
  • min(Collection coll, Comparator comp):根据自定义比较器,返回最小元素
  • fill(List list, Object obj):使用指定对象填充
  • frequency(Collection Object o):返回指定集合中指定对象出现的次数
  • replaceAll(List list, Object old, Object new):替换

4.创建空集合

Collections提供了一系列方法来创建空集合:
创建空List:List<T> emptyList()
创建空Map:Map<K, V> emptyMap()
创建空Set:Set<T> emptySet()
要注意到返回的空集合是不可变集合,无法向其中添加或删除元素。

此外,也可以用各个集合接口提供的of(T...)方法创建空集合。例如,以下创建空List的两个方法是等价的:

List<String> list1 = List.of();
List<String> list2 = Collections.emptyList();

创建新的集合现在都在用Guava 的Lists.asList(),之后再记录一下

  public static <E> List<E> asList(@Nullable E first, E[] rest) {
    return new OnePlusArrayList<E>(first, rest);
  }

5.创建单元素集合

Collections提供了一系列方法来创建一个单元素集合:

创建一个元素的List:List<T> singletonList(T o)
创建一个元素的Map:Map<K, V> singletonMap(K key, V value)
创建一个元素的Set:Set<T> singleton(T o)
要注意到返回的单元素集合也是不可变集合,无法向其中添加或删除元素。

此外,也可以用各个集合接口提供的of(T...)方法创建单元素集合。例如,以下创建单元素List的两个方法是等价的:

List<String> list1 = List.of("apple");
List<String> list2 = Collections.singletonList("apple");

实际上,使用List.of(T...)更方便,因为它既可以创建空集合,也可以创建单元素集合,还可以创建任意个元素的集合:

List<String> list1 = List.of(); // empty list
List<String> list2 = List.of("apple"); // 1 element
List<String> list3 = List.of("apple", "pear"); // 2 elements
List<String> list4 = List.of("apple", "pear", "orange"); // 3 elements

6.不可变集合

Collections还提供了一组方法把可变集合封装成不可变集合:

封装成不可变List:List<T> unmodifiableList(List<? extends T> list)
封装成不可变Set:Set<T> unmodifiableSet(Set<? extends T> set)
封装成不可变Map:Map<K, V> unmodifiableMap(Map<? extends K, ? extends V> m)
这种封装实际上是通过创建一个代理对象,拦截掉所有修改方法实现的。类似与Guava 的ImmutableMap我的另一篇Guava 的ImmutableMap

7.线程安全集合

自从有了juc,基本没啥用,就不写了。

不要以为每天把功能完成了就行了,这种思想是要不得的,互勉~!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。