说一说 Collections 工具类的用法总结

简介: 我是小假 期待与你的下一次相遇 ~

1、排序操作

  • reverse(List list):反转顺序
  • shuffle(List list):洗牌,将顺序打乱
  • sort(List list):自然升序
  • sort(List list, Comparator c):按照自定义的比较器排序
  • swap(List list, int i, int j):将 i 和 j 位置的元素交换位置

来看例子:

  1. List<String> list = new ArrayList<>();
  2. list.add("二");
  3. list.add("三");
  4. list.add("四");
  5. list.add("五");
  6. list.add("六");
  7. System.out.println("原始顺序:" + list);
  8. // 反转
  9. Collections.reverse(list);
  10. System.out.println("反转后:" + list);
  11. // 洗牌
  12. Collections.shuffle(list);
  13. System.out.println("洗牌后:" + list);
  14. // 自然升序
  15. Collections.sort(list);
  16. System.out.println("自然升序后:" + list);
  17. // 交换
  18. Collections.swap(list, 2,4);
  19. System.out.println("交换后:" + list);

输出后:

  1. 原始顺序:[二, 三, 四, 五, 六]
  2. 反转后:[六, 五, 四, 三, 二]
  3. 洗牌后:[五, 二, 六, 三, 四]
  4. 自然升序后:[三, 二, 五, 六, 四]
  5. 交换后:[三, 二, 四, 六, 五]

2、查找操作

  • 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 c, Object o):返回指定对象出现的次数

来看例子:

  1. System.out.println("最大元素:" + Collections.max(list));
  2. System.out.println("最小元素:" + Collections.min(list));
  3. System.out.println("出现的次数:" + Collections.frequency(list, "二"));
  4. // 没有排序直接调用二分查找,结果是不确定的
  5. System.out.println("排序前的二分查找结果:" + Collections.binarySearch(list, "二"));
  6. Collections.sort(list);
  7. // 排序后,查找结果和预期一致
  8. System.out.println("排序后的二分查找结果:" + Collections.binarySearch(list, "二"));
  9. Collections.fill(list, "八");
  10. System.out.println("填充后的结果:" + list);

输出后:

  1. 原始顺序:[二, 三, 四, 五, 六]
  2. 最大元素:四
  3. 最小元素:三
  4. 出现的次数:1
  5. 排序前的二分查找结果:0
  6. 排序后的二分查找结果:1
  7. 填充后的结果:[八, 八, 八, 八, 八]

3、同步控制

HashMap 是线程不安全的,其实 ArrayList 也是线程不安全的,没法在多线程环境下使用,那 Collections 工具类中提供了多个 synchronizedXxx 方法,这些方法会返回一个同步的对象,从而解决多线程中访问集合时的安全问题。

使用起来也非常的简单:

  1. SynchronizedList synchronizedList = Collections.synchronizedList(list);

看一眼 SynchronizedList 的源码就明白了,不过是在方法里面使用 synchronized 关键字加了一层锁而已。

  1. static class SynchronizedList<E>
  2.    extends SynchronizedCollection<E>
  3.    implements List<E> {
  4.    private static final long serialVersionUID = -7754090372962971524L;
  5.    final List<E> list;
  6.    SynchronizedList(List<E> list) {
  7.        super(list);
  8.        this.list = list;
  9.    }
  10.    public E get(int index) {
  11.        synchronized (mutex) {return list.get(index);}
  12.    }
  13.    public void add(int index, E element) {
  14.        synchronized (mutex) {list.add(index, element);}
  15.    }
  16.    public E remove(int index) {
  17.        synchronized (mutex) {return list.remove(index);}
  18.    }
  19. }

那这样的话,其实效率和那些直接在方法上加 synchronized 关键字的 VectorHashtable 差不多(JDK 1.0 时期就有了),而这些集合类基本上已经废弃了,几乎不怎么用。

  1. public class Vector<E>
  2.    extends AbstractList<E>
  3.    implements List<E>, RandomAccess, Cloneable, java.io.Serializable
  4. {
  5.    public synchronized E get(int index) {
  6.        if (index >= elementCount)
  7.            throw new ArrayIndexOutOfBoundsException(index);
  8.        return elementData(index);
  9.    }
  10.    public synchronized E remove(int index) {
  11.        modCount++;
  12.        if (index >= elementCount)
  13.            throw new ArrayIndexOutOfBoundsException(index);
  14.        E oldValue = elementData(index);
  15.        int numMoved = elementCount - index - 1;
  16.        if (numMoved > 0)
  17.            System.arraycopy(elementData, index+1, elementData, index,
  18.                             numMoved);
  19.        elementData[--elementCount] = null; // Let gc do its work
  20.        return oldValue;
  21.    }
  22. }

正确的做法是使用并发包下的 CopyOnWriteArrayListConcurrentHashMap。这些放到并发编程时再讲。

4、不可变集合

  • emptyXxx():制造一个空的不可变集合
  • singletonXxx():制造一个只有一个元素的不可变集合
  • unmodifiableXxx():为指定集合制作一个不可变集合

举个例子:

  1. List emptyList = Collections.emptyList();
  2. emptyList.add("非空");
  3. System.out.println(emptyList);

这段代码在执行的时候就抛出错误了。

  1. Exception in thread "main" java.lang.UnsupportedOperationException
  2. at java.util.AbstractList.add(AbstractList.java:148)
  3. at java.util.AbstractList.add(AbstractList.java:108)
  4. at com.itwanger.s64.Demo.main(Demo.java:61)

这是因为 Collections.emptyList() 会返回一个 Collections 的内部类 EmptyList,而 EmptyList 并没有重写父类 AbstractList 的 add(int index, E element) 方法,所以执行的时候就抛出了不支持该操作的 UnsupportedOperationException 了。

这是从分析 add 方法源码得出的原因。除此之外,emptyList 方法是 final 的,返回的 EMPTY_LIST 也是 final 的,种种迹象表明 emptyList 返回的就是不可变对象,没法进行增伤改查。

  1. public static final <T> List<T> emptyList() {
  2.    return (List<T>) EMPTY_LIST;
  3. }
  4. public static final List EMPTY_LIST = new EmptyList<>();

5、其他

还有两个方法比较常用:

  • addAll(Collection<? super T> c, T... elements),往集合中添加元素
  • disjoint(Collection<?> c1, Collection<?> c2),判断两个集合是否没有交集

举个例子:

  1. List<String> allList = new ArrayList<>();
  2. Collections.addAll(allList, "九","十","二");
  3. System.out.println("addAll 后:" + allList);
  4. System.out.println("是否没有交集:" + (Collections.disjoint(list, allList) ? "是" : "否"));

输出后:

  1. 原始顺序:[二, 三, 四, 五, 六]
  2. addAll 后:[九, 十, 二]
  3. 是否没有交集:否

整体上,Collections 工具类作为集合框架的大管家,提供了一些非常便利的方法。


相关文章
常用工具类-Collections
本文介绍了Java中Collections工具类的功能和用法,包括对集合进行排序、查找、填充操作,判断集合是否有交集,以及创建不可变集合的方法。通过示例代码展示了如何使用Collections类提供的静态方法,如reverse、shuffle、sort、swap、binarySearch、max、min、fill、frequency、disjoint、emptyList等,突出了Collections类在操作集合时的便利性和实用性。
常用工具类-Collections
|
10月前
|
JavaScript 前端开发 测试技术
Playwright自动化测试系列课(4) | 异步加载克星:自动等待 vs 智能等待策略深度解析​
本文深度解析Playwright自动化测试中的等待策略,对比自动等待(零配置防御机制)与智能等待(精准控制异步场景)的核心差异。通过实战案例讲解等待机制的选择标准、常见失效原因及调试技巧,帮助开发者有效解决页面异步加载问题,提升测试脚本的稳定性和执行效率。
|
11月前
|
JSON IDE Java
20 款 IDEA 主题任你选!(快来看看你最喜欢那个~)
我是小假 期待与你的下一次相遇 ~
5765 1
|
存储 SQL NoSQL
mybatis-plus小技能: 分表策略(按年分表和按月分表)
业务场景: 日志、交易流水表或者其他数据量大的表,通过日期进行了水平分表,需要通过日期参数,动态的查询数据。 实现思路:利用MybatisPlus的动态表名插件DynamicTableNameInnerInterceptor ,实现Sql执行时,动态的修改表名。
9803 3
mybatis-plus小技能: 分表策略(按年分表和按月分表)
|
SQL 分布式计算 DataWorks
利用DataWorks构建高效数据管道
【8月更文第25天】本文将详细介绍如何使用阿里云 DataWorks 的数据集成服务来高效地收集、清洗、转换和加载数据。我们将通过实际的代码示例和最佳实践来展示如何快速构建 ETL 流程,并确保数据管道的稳定性和可靠性。
665 56
|
XML JSON Java
万字SpringBoot学习笔记|菜鸟版
Spring Boot是Pivotal团队在Spring的基础上提供的一套全新的开源框架,其目的是为了简化Spring应用的搭建和开发过程。Spring Boot去除了大量的XML配置文件,简化了复杂的依赖管理。 官网地址:spring.io/projects/sp… Spring Boot入门 简介 Spring Boot是简化Spring应用开发的一个框架、整个Spring技术栈的一个大整合(Spring全家桶时代)、J2EE开发的一站式解决方案(Spring Cloud是分布式整体解决方案)。 优点: – 快速创建独立运行的Spring项目以及与主流框架集成 – 使用嵌入式的Serv
492 0
|
负载均衡 监控 Java
SpringCloud常见面试题(一):SpringCloud 5大组件,服务注册和发现,nacos与eureka区别,服务雪崩、服务熔断、服务降级,微服务监控
SpringCloud常见面试题(一):SpringCloud 5大组件,服务注册和发现,nacos与eureka区别,服务雪崩、服务熔断、服务降级,微服务监控
32686 8
SpringCloud常见面试题(一):SpringCloud 5大组件,服务注册和发现,nacos与eureka区别,服务雪崩、服务熔断、服务降级,微服务监控
|
SQL 监控 关系型数据库
mysql每次最大插入条数
综上所述,虽然MySQL没有严格限制每次插入操作的最大条数,但实际操作中应综合考虑多种因素,采取适当策略来确保数据插入的高效与稳定。
891 1

热门文章

最新文章