Collections工具类源码学习

目前在学习java集合类的源码思想,本文将Collections工具类完整学习了一遍,达到学有所用的地步,留下记录便于复习。【标题党,还没写完】

Collections 工具类封装了很多集合类相关的操作方法,合理学习和利用说不定可以给编程思路提供不错的启发,同时也可以提升自己的代码质量。

先整体看看有哪些方法吧

首先是静态内部类,可以直接通过类名使用,也可以通过开放的方法获取,这部分是对集合的整体操作,返回集合的不可变、同步以及动态的安全视图

还有部分私有静态内部类,只能通过对应的开放方法获取,可以获得集合的空集,单例集合等

对应以上内部类的操作方法如下

除了提供对集合的处理,还提供了对集合内部元素的处理,有对应以下的方法完成对元素的排序、查找、最大最小值、定位等操作

元素操作中用到的私有方法如下

最后还有比较多面的操作

初始化集合Set、Map、List,分别添加七个元素

List<Integer> list = new ArrayList<Integer>() {{
        add(1);
        add(3);
        add(5);
        add(2);
        add(4);
        add(6);
        add(-1);
    }};
Set<Integer> set = new HashSet<Integer>() {{
        add(1);
        add(3);
        add(5);
        add(2);
        add(4);
        add(6);
        add(-1);
    }};
Map<Integer, Integer> mapMap<Integer, Integer> map = new HashMap<Integer, Integer>() {{
        put(1, 1);
        put(3, 3);
        put(5, 5);
        put(2, 2);
        put(4, 4);
        put(6, 6);
        put(-1, -1);
    }};

对集合的操作

Unmodifiable* 不可变集合

以Unmodifiable开头的都是返回不可修改的视图,只允许对集合执行只读操作,若直接对集合元素进行修改,会抛出UnsupportedOperationException异常。这样的集合类在并发场景下更安全,性能更高吧。

  • UnmodifiableCollection、 UnmodifiableSet、UnmodifiableList

    //遍历不可变集合,其他两个类操作相同,初始化类型对应即可
    Collections.unmodifiableSet(set).forEach((num) -> System.out.println(num)); // 1,3,5,2,4,6,-1
    
    //异常被捕获
    try {
        Collections.unmodifiableSet(set).add(3);
    } catch (UnsupportedOperationException e) {
        System.out.println("无法改变不可变类");
    }
    
  • UnmodifiableSortedSet、UnmodifiableNavigableSet、UnmodifiableSortedMap、UnmodifiableNavigableMap

    这四个集合类是将set和map返回一个默认升序的不可变视图,list本身就支持排序,所以就没有对应的方法。UnmodifiableSortedSet继承自UnmodifiableSet,并实现了SortedSet接口。而UnmodifiableNavigableSet相应继承自UnmodifiableSortedSet,并实现了NavigableSet接口。Map如是。

    看起来挺复杂,其实把UnmodifiableNavigableSet看成TreeSet的不可变集合就可以了。关于TreeSet

    // UnmodifiableSortedSet相关操作,只是不能修改。
    Collections.unmodifiableSortedSet(new TreeSet<>(set)).forEach((num) -> System.out.println(num)); // -1,1,2,3,4,5,6
    
    System.out.println(Collections.unmodifiableSortedSet(new TreeSet<>(set)).first()); // -1
    System.out.println(Collections.unmodifiableSortedSet(new TreeSet<>(set)).last()); // 6
    
    //异常被捕获
    try {
        Collections.unmodifiableSortedSet(new TreeSet<>(set)).add(3);
    } catch (UnsupportedOperationException e) {
        System.out.println("无法改变不可变类");
    }
    
    // unmodifiableNavigableSet比上个类多了NavigableSet接口中的几个方法,和treeset的操作无异(除了不能修改)
    Collections.unmodifiableNavigableSet(new TreeSet<>(set)).forEach((num) -> System.out.println(num));
    System.out.println(Collections.unmodifiableNavigableSet(new TreeSet<>(set)).floor(3)); // 3
    System.out.println(Collections.unmodifiableNavigableSet(new TreeSet<>(set)).lower(3)); // 2
    //异常被捕获
    try {
        Collections.unmodifiableNavigableSet(new TreeSet<>(set)).add(3);
    } catch (UnsupportedOperationException e) {
        System.out.println("无法改变不可变类");
    }
    // map对应的操作一致,并且TreeSet是借助TreeMap完成的排序
    
  • UnmodifiableRandomAccessList

    继承自UnmodifiableList,实现RandomAccess接口。【RandomAccess接口是一个空接口,只是作为标识符使用,在某些排序、查找方法中对实现了该接口的采用不同的算法,使得查找效率更高。后面在元素操作方法中会介绍。】
    在UnmodifiableList基础上只添加了subList,使得可以通过快速访问的方式获取指定范围的子串。

对元素的操作

Fork me on GitHub