阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

使用Collections

79次阅读
没有评论

共计 2851 个字符,预计需要花费 8 分钟才能阅读完成。

Collections是 JDK 提供的工具类,同样位于 java.util 包中。它提供了一系列静态方法,能更方便地操作各种集合。

注意

Collections 结尾多了一个 s,不是 Collection!

我们一般看方法名和参数就可以确认 Collections 提供的该方法的功能。例如,对于以下静态方法:

public static boolean addAll(Collection<? super T> c, T... elements) {...}

addAll()方法可以给一个 Collection 类型的集合添加若干元素。因为方法签名是 Collection,所以我们可以传入ListSet 等各种集合类型。

创建空集合

对于旧版的 JDK,可以使用 Collections 提供的一系列方法来创建空集合:

  • 创建空 List:List<T> emptyList()
  • 创建空 Map:Map<K, V> emptyMap()
  • 创建空 Set:Set<T> emptySet()

要注意到返回的空集合是不可变集合,无法向其中添加或删除元素。

新版的 JDK≥9 可以直接使用 List.of()Map.of()Set.of() 来创建空集合。

创建单元素集合

对于旧版的 JDK,Collections提供了一系列方法来创建一个单元素集合:

  • 创建一个元素的 List:List<T> singletonList(T o)
  • 创建一个元素的 Map:Map<K, V> singletonMap(K key, V value)
  • 创建一个元素的 Set:Set<T> singleton(T o)

要注意到返回的单元素集合也是不可变集合,无法向其中添加或删除元素。

新版的 JDK≥9 可以直接使用 List.of(T...)Map.of(T...)Set.of(T...) 来创建任意个元素的集合。

排序

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

import java.util.*;

public class Main {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);
    }
}

洗牌

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

import java.util.*;

public class Main {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);
    }
}

不可变集合

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)

这种封装实际上是通过创建一个代理对象,拦截掉所有修改方法实现的。我们来看看效果:

import java.util.*;

public class Main {public static void main(String[] args) {List<String> mutable = new ArrayList<>();
        mutable.add("apple");
        mutable.add("pear");
        // 变为不可变集合:
        List<String> immutable = Collections.unmodifiableList(mutable);
        immutable.add("orange"); // UnsupportedOperationException!
    }
}

然而,继续对原始的可变 List 进行增删是可以的,并且,会直接影响到封装后的“不可变”List

import java.util.*;

public class Main {public static void main(String[] args) {List<String> mutable = new ArrayList<>();
        mutable.add("apple");
        mutable.add("pear");
        // 变为不可变集合:
        List<String> immutable = Collections.unmodifiableList(mutable);
        mutable.add("orange");
        System.out.println(immutable);
    }
}

因此,如果我们希望把一个可变 List 封装成不可变 List,那么,返回不可变List 后,最好立刻扔掉可变 List 的引用,这样可以保证后续操作不会意外改变原始对象,从而造成“不可变”List变化了:

import java.util.*;

public class Main {public static void main(String[] args) {List<String> mutable = new ArrayList<>();
        mutable.add("apple");
        mutable.add("pear");
        // 变为不可变集合:
        List<String> immutable = Collections.unmodifiableList(mutable);
        // 立刻扔掉 mutable 的引用:
        mutable = null;
        System.out.println(immutable);
    }
}

线程安全集合

Collections还提供了一组方法,可以把线程不安全的集合变为线程安全的集合:

  • 变为线程安全的 List:List<T> synchronizedList(List<T> list)
  • 变为线程安全的 Set:Set<T> synchronizedSet(Set<T> s)
  • 变为线程安全的 Map:Map<K,V> synchronizedMap(Map<K,V> m)

多线程的概念我们会在后面讲。因为从 Java 5 开始,引入了更高效的并发集合类,所以上述这几个同步方法已经没有什么用了。

小结

Collections类提供了一组工具方法来方便使用集合类:

  • 创建空集合;
  • 创建单元素集合;
  • 创建不可变集合;
  • 排序/洗牌等操作。

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2024-08-05发表,共计2851字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中