java 集合 之 集合工具类Collections

前言

        早期开发者经常需要对集合进行各种操作

        比如排序、查找最大最小值等等

        但是当时没有统一的工具类来处理

        所以导致代码重复且容易出错

        

        java.util.Collections 工具类的引入

        为开发者提供了大量 静态方法 操作集合

        它就像一个经验丰富的助手

        和数组工具类 Arrays 一样

        避免了我们重复造轮子的情况

一、Collections 工具类概述

java.util.Collections 是一个操作集合的工具类

提供大量 静态方法 操作 返回 集合

源码:

// Collections 类的声明
public class Collections {// 私有构造函数,防止实例化private Collections() {}// ... 大量静态方法
}

通过源码我们可以看出:

  • Collections 是一个很纯粹的工具类
  • 没有继承,没有实现,父类是 Object
  • 构造器私有,不能实例化对象 

注意区分:

        Collections 是集合的工具类

        Collection   是单列集合的根接口

二、核心方法

1、addAll

方法声明:

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

调用者:

        Collections

参数:

        Collection<? super T>c :目标集合

        T...elements :要添加的元素(可变参)

       

泛型中,我们常见三种形式:

1、T                        具体类型参数

2、?extends T      上界通配符,表示T或T的子类型

3、?super T          下界通配符,表示T或T的父类型

                        

返回值:

        boolean,如果集合被修改则返回true

作用:

        将多个元素一次性添加到集合中

是否改变原始值:

        是,会修改目标集合

源码:

public static <T> boolean addAll(Collection<? super T> c, T... elements) {boolean result = false;for (T element : elements)result |= c.add(element);return result;
}

源码解读:

  • 使用可变参 T...elements 接收任意数量的元素
  • 遍历所有元素,逐个添加到集合中
  • 使用 位或运算 |= 累计添加结果,只要有元素成功添加就返回true

示例:

import java.util.*;public class AddAllExample {public static void main(String[] args) {List<String> fruits = new ArrayList<>();// 使用 Collections.addAll 批量添加元素Collections.addAll(fruits, "apple", "banana", "orange", "grape");System.out.println("水果列表: " + fruits);// 输出: 水果列表: [apple, banana, orange, grape]// 对比传统方式List<String> vegetables = new ArrayList<>();vegetables.add("carrot");vegetables.add("potato");vegetables.add("tomato");System.out.println("蔬菜列表: " + vegetables);// 输出: 蔬菜列表: [carrot, potato, tomato]}
}

2、sort

方法声明:

        //自然排序版本

        public static <T extends Comparable<? super T>> void sort(List<T> list)

        //比较器排序版本

        public static <T> void sort(List<T> list, Comparator<? super T> c)

调用者:

        Collections

参数:

        List<T> list:要排序的列表

        Comparator<?super T>c:比较器(可选)

返回值:

        void

作用:

        对列表进行排序

是否改变原始值:

        是,会修改原列表

注意事项:

        自然排序要求实现 Comparable 接口

源码:

// 自然排序版本
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);
}

源码解读:

实际上是委托给 List 接口的 sort 方法实现

JDK 8 之后,List 接口增加了默认方法 sort,Collections.sort 成为了该方法的包装

JDK 8 之前 Collections.sort() 实现:

// JDK 8 之前的 Collections.sort() 实现(简化版)
public static <T extends Comparable<? super T>> void sort(List<T> list) {Object[] a = list.toArray();Arrays.sort(a);ListIterator<T> i = list.listIterator();for (int j=0; j<a.length; j++) {i.next();i.set((T)a[j]);}
}

JDK 8 之后 List 接口新增的默认方法:

// List 接口中的默认方法 sort()
default void sort(Comparator<? super E> c) {Object[] a = this.toArray();Arrays.sort(a, (Comparator) c);ListIterator<E> i = this.listIterator();for (int j=0; j<a.length; j++) {i.next();i.set((E) a[j]);}
}

JDK 8 之后 Collections.sort() 实现:

// JDK 8 之后 Collections.sort() 的实现(简化版)
public static <T extends Comparable<? super T>> void sort(List<T> list) {list.sort(null); // 委托给 List.sort() 方法
}public static <T> void sort(List<T> list, Comparator<? super T> c) {list.sort(c); // 委托给 List.sort() 方法
}

总结一下:

  1. 功能转移:排序核心功能被转移到了 List 接口中
  2. 实现委托:Collections.sort() 方法现在内部调用 List.sort() 来实现排序功能

示例:

import java.util.*;public class SortExample {public static void main(String[] args) {// 自然排序示例List<Integer> numbers = new ArrayList<>();Collections.addAll(numbers, 5, 2, 8, 1, 9);System.out.println("排序前: " + numbers);Collections.sort(numbers); // 自然排序System.out.println("自然排序后: " + numbers);// 输出: 自然排序后: [1, 2, 5, 8, 9]// 比较器排序示例(降序)List<String> words = new ArrayList<>();Collections.addAll(words, "banana", "apple", "cherry");System.out.println("排序前: " + words);Collections.sort(words, Collections.reverseOrder()); // 降序排序System.out.println("降序排序后: " + words);// 输出: 降序排序后: [cherry, banana, apple]}
}

3、reverse

方法声明:

        public static void reverse(List<?> list)

调用者:

        Collections

参数:

        List<?> list :要反转的列表 

返回值:

        void

作用:

        反转集合中的元素顺序

是否改变原始值:

        是,会修改原集合

注意事项:

        只适用于 List 类型的集合

源码:

public static void reverse(List<?> list) {int size = list.size();if (size < REVERSE_THRESHOLD || list instanceof RandomAccess) {// 对于小列表或随机访问列表,直接交换元素for (int i=0, mid=size>>1, j=size-1; i<mid; i++, j--)swap(list, i, j);} else {// 对于大列表且非随机访问,使用ListIteratorListIterator fwd = list.listIterator();ListIterator rev = list.listIterator(size);for (int i=0, mid=list.size()>>1; i<mid; i++) {Object tmp = fwd.next();fwd.set(rev.previous());rev.set(tmp);}}
}

源码解读:

  • 根据列表大小和是否实现 RandomAccess 接口选择不同的实现策略
  • 小列表或者随机访问列表采用直接索引交换的方式
  • 大列表且非随机访问采用 LIstIterator

示例:

import java.util.*;public class ReverseExample {public static void main(String[] args) {List<String> colors = new ArrayList<>();Collections.addAll(colors, "red", "green", "blue", "yellow");System.out.println("反转前: " + colors);// 输出: 反转前: [red, green, blue, yellow]Collections.reverse(colors);System.out.println("反转后: " + colors);// 输出: 反转后: [yellow, blue, green, red]}
}

4、shuffle

方法声明:

        public static void shuffle(List<?> list)

        public static void shuffle(List<?> list, Random rnd)

调用者:

        Collections

参数:

        List<?> list:要打乱的集合

        Random rnd:随机数生成器(可选)   

返回值:

        void

作用:

        随机打乱列表中的元素顺序

是否改变原始值:

        是,会修改原集合

注意事项:

        可以传入自定义的Random对象以控制随机种子

源码:

public static void shuffle(List<?> list) {Random rnd = r;if (rnd == null)r = rnd = new Random();shuffle(list, rnd);
}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();for (int i=size; i>1; i--)swap(arr, i-1, rnd.nextInt(i));ListIterator it = list.listIterator();for (int i=0; i<arr.length; i++) {it.next();it.set(arr[i]);}}
}

源码解读:

  • 使用 Fisher-Yates 洗牌算法实现随机打乱
  • 根据列表大小和是否实现 RandomAccess 接口选择不同的实现策略

示例:

import java.util.*;public class ShuffleExample {public static void main(String[] args) {List<Integer> cards = new ArrayList<>();for (int i = 1; i <= 10; i++) {cards.add(i);}System.out.println("洗牌前: " + cards);Collections.shuffle(cards);System.out.println("洗牌后: " + cards);// 使用固定种子的随机数生成器Collections.shuffle(cards, new Random(123));System.out.println("固定种子洗牌: " + cards);}
}

5、max/min

方法声明:

        public static <T> T min(Collection<? extends T> coll, Comparator<? super T> comp)

        public static <T extends Object & Comparable<? super T>> T min(Collection<? extends T> coll)

调用者:

        Collections

参数:

        Collection<? extends T> coll:要查找的集合

        Comparator<? super T> comp:比较器(可选)

返回值:

        T,集合中的最大或最小元素

作用:

        查找集合中的最大或最小元素

是否改变原始值:

        否,不修改原集合

注意事项:

        自然排序要求实现 Comparable 接口

        空集合会抛出 NoSuchElementException

源码:

public static <T extends Object & Comparable<? super T>> T min(Collection<? extends T> coll) {Iterator<? extends T> i = coll.iterator();T candidate = i.next();while (i.hasNext()) {T next = i.next();if (next.compareTo(candidate) < 0)candidate = next;}return candidate;
}public static <T> T min(Collection<? extends T> coll, Comparator<? super T> comp) {if (comp==null)return (T)min((Collection) coll);Iterator<? extends T> i = coll.iterator();T candidate = i.next();while (i.hasNext()) {T next = i.next();if (comp.compare(next, candidate) < 0)candidate = next;}return candidate;
}

源码解读:

  • 通过迭代器遍历集合,比较元素大小
  • 自然排序使用 compareTo 方法,比较器排序使用 compare 方法

示例:

import java.util.*;public class MaxMinExample {public static void main(String[] args) {List<Integer> numbers = new ArrayList<>();Collections.addAll(numbers, 10, 5, 8, 3, 15, 7);Integer max = Collections.max(numbers);Integer min = Collections.min(numbers);System.out.println("数字列表: " + numbers);System.out.println("最大值: " + max); // 输出: 最大值: 15System.out.println("最小值: " + min); // 输出: 最小值: 3// 使用自定义比较器(按绝对值比较)List<Integer> negativeNumbers = new ArrayList<>();Collections.addAll(negativeNumbers, -10, 5, -8, 3);// 按绝对值找最大值Integer maxAbs = Collections.max(negativeNumbers, Comparator.comparing(Math::abs));System.out.println("绝对值最大: " + maxAbs); // 输出: 绝对值最大: -10}
}

6、fill

方法声明:

        public static <T> void fill(List<? super T> list, T obj)

调用者:

        Collections

参数:

        List<? super T> list:要填充的集合

        T obj:用于填充的对象

返回值:

        void

作用:

        使用指定的元素替换集合中的所有元素

是否改变原始值:

        是,会修改原集合

注意事项:

        集合必须已经有元素,不能是空列表

源码:

public static <T> void fill(List<? super T> list, T obj) {int size = list.size();if (size < FILL_THRESHOLD || list instanceof RandomAccess) {for (int i=0; i<size; i++)list.set(i, obj);} else {ListIterator<? super T> itr = list.listIterator();for (int i=0; i<size; i++) {itr.next();itr.set(obj);}}
}

源码解读:

  • 根据列表大小和是否实现 RandomAccess 接口选择不同的实现策略
  • 使用索引或迭代器将所有元素替换为指定对象

示例:

import java.util.*;public class FillExample {public static void main(String[] args) {List<String> list = new ArrayList<>(Arrays.asList(new String[5]));System.out.println("填充前: " + list);Collections.fill(list, "default");System.out.println("填充后: " + list);// 输出: 填充后: [default, default, default, default, default]// 也可以用于初始化List<Integer> numbers = new ArrayList<>(Collections.nCopies(5, 0));System.out.println("初始化: " + numbers);Collections.fill(numbers, 1);System.out.println("填充为1: " + numbers);}
}

7、binarySearch

方法声明:

        public static <T> int binarySearch(List<? extends Comparable<? super T>> list, T key)

        private static <T> int indexedBinarySearch(List<? extends Comparable<? super T>> list, T key)

调用者:

        Collections

参数:

        List<? extends Comparable<? super T>> list:已降序的集合

        T key:要查找的键

        Comparator<? super T> c:比较器(可选) 

返回值:

        int,找到则返回索引,未找到则返回负数

作用:

        在已排序集合中查找指定元素

是否改变原始值:

        否,不修改原集合

注意事项:

        集合必须已经排序

        返回值为负数时表示未找到,其绝对值减 1 是应该插入的位置

源码:

public static <T> int binarySearch(List<? extends Comparable<? super T>> list, T key) {if (list instanceof RandomAccess || list.size()<BINARYSEARCH_THRESHOLD)return Collections.indexedBinarySearch(list, key);elsereturn Collections.iteratorBinarySearch(list, key);
}private static <T> int indexedBinarySearch(List<? extends Comparable<? super T>> list, T key) {int low = 0;int high = list.size()-1;while (low <= high) {int mid = (low + high) >>> 1;Comparable<? super T> midVal = list.get(mid);int cmp = midVal.compareTo(key);if (cmp < 0)low = mid + 1;else if (cmp > 0)high = mid - 1;elsereturn mid; // key found}return -(low + 1);  // key not found
}

源码解读:

  • 实现标准的二分查找算法
  • 根据列表是否实现 RandomAccess 接口选择不同的实现策略

示例:

import java.util.*;public class BinarySearchExample {public static void main(String[] args) {List<Integer> sortedList = new ArrayList<>();Collections.addAll(sortedList, 1, 3, 5, 7, 9, 11, 13);int index = Collections.binarySearch(sortedList, 7);System.out.println("元素7的索引: " + index); // 输出: 元素7的索引: 3int notFoundIndex = Collections.binarySearch(sortedList, 6);System.out.println("元素6的索引: " + notFoundIndex); // 输出: 元素6的索引: -4System.out.println("应该插入的位置: " + (Math.abs(notFoundIndex) - 1)); // 输出: 应该插入的位置: 3}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/93434.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/93434.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025 年电赛 C 题 发挥部分 1:多正方形 / 重叠正方形高精度识别与最小边长测量

2025 年全国大学生电子设计竞赛 C 题 发挥部分 1&#xff1a;多正方形 / 重叠正方形高精度识别与最小边长测量 香橙派 OpenCV C 全流程解析 目录 赛题背景与需求技术难点全景图系统总体架构硬件平台与接线软件架构与线程模型算法流水线逐帧拆解 6.1 图像预处理6.2 轮廓提取与…

【自动驾驶】自动驾驶概述 ② ( 自动驾驶技术路径 | L0 ~ L5 级别自动驾驶 )

文章目录一、自动驾驶技术路径1、L0 级别 自动驾驶2、L1 级别 自动驾驶3、L2 级别 自动驾驶4、L3 级别 自动驾驶5、L4 级别 自动驾驶6、L5 级别 自动驾驶一、自动驾驶技术路径 美国汽车工程师学会 ( SAE ) 将 自动驾驶 分为 L0 ~ L5 六个级别 : 其中 L0 级别 是 完全手动 , L5…

C++少儿编程(二十二)—条件结构

1.理解条件结构小朋友们&#xff0c;今天让我们一起来探索一个神奇而有趣的知识——程序的条件结构&#xff01;首先&#xff0c;让我们来想象一个有趣的场景。比如说&#xff0c;你们正在准备去公园玩耍。在出发之前&#xff0c;你们会看看天气怎么样。如果天气晴朗&#xff0…

Ubuntu20.04下Px4使用UORB发布消息

1 .msg文件夹定义数据类型及 变量名文件位置如图&#xff0c;在PX4-Autopilot/msg文件夹下&#xff0c;笔者创建的文件名为gps_msg.msggps_msg.msg内容如下 uint64 timestamp # 时间戳 float32 latitude float32 longitude float32 altitude 同时&#xff0c;在CM…

three.js学习记录(第二节:鼠标控制相机移动)

效果展示&#xff1a; 鼠标控制一、鼠标控制 - 轨道控制器&#xff08;OrbitControls&#xff09; 1. 从nodeModules中导入OrbitControls&#xff0c;OrbitControls 是一个附加组件&#xff0c;必须显式导入 import { OrbitControls } from "three/examples/jsm/controls/…

Shortest Routes II(Floyd最短路)

题目描述There are n cities and m roads between them. Your task is to process q queries where you have to determine the length of the shortest route between two given cities.输入The first input line has three integers n, m and q: the number of cities, roads…

分享一个基于Hadoop的二手房销售签约数据分析与可视化系统,基于Python可视化的二手房销售数据分析平台

&#x1f495;&#x1f495;作者&#xff1a;计算机源码社 &#x1f495;&#x1f495;个人简介&#xff1a;本人八年开发经验&#xff0c;擅长Java、Python、PHP、.NET、Node.js、Spark、hadoop、Android、微信小程序、爬虫、大数据、机器学习等&#xff0c;大家有这一块的问题…

STM32的PWM

PWM作为硬件中几乎不可或缺的存在&#xff0c;学会 PWM&#xff0c;等于打通了 STM32 的“定时器体系”。学一次&#xff0c;STM32 全系列&#xff08;甚至 AVR、PIC、ESP32&#xff09;都能通用。硬件只要一个 I/O 就能驱动功率模块&#xff0c;非常省成本。不会 PWM&#xff…

OpenCompass傻瓜式入门教程

文章目录1 我也许不是傻瓜&#xff0c;却只想做个傻瓜2 环境要求3 安装3.1 下载源码3.2 创建虚拟环境3.3 安装4 下载数据5 查看支持的模型和数据集6 评测6.1 指定模型路径6.2 指定配置文件6.2.1 评测本地qwen2.5模型6.2.1.1 查看opencompass支持的qwen2.5模型6.2.1.2 创建配置文…

【软件测试】电商购物项目-各个测试点整理(三)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、优惠券的测试点…

流处理、实时分析与RAG驱动的Python ETL框架:构建智能数据管道(上)

> **2025年某电商大促,每秒20万订单涌入系统**——他们的风控团队仅用**47毫秒**就识别出欺诈交易。背后的秘密武器,正是融合流处理、实时分析与RAG的下一代Python ETL框架。 ### 一、范式革命:从批处理到AI增强的ETL 4.0 #### 1.1 数据处理演进史 ```mermaid graph LR …

开源 Arkts 鸿蒙应用 开发(十五)自定义绘图控件--仪表盘

文章的目的为了记录使用Arkts 进行Harmony app 开发学习的经历。本职为嵌入式软件开发&#xff0c;公司安排开发app&#xff0c;临时学习&#xff0c;完成app的开发。开发流程和要点有些记忆模糊&#xff0c;赶紧记录&#xff0c;防止忘记。 相关链接&#xff1a; 开源 Arkts …

​​​​​​​中国工业企业专利及引用被引用数据说明

1319 中国工业企业专利及引用被引用数据说明数据简介专利近年发文趋势及主题分布今天数据皮皮侠团队为大家分享一份2023年12月25日最新更新的中国工业企业专利及引用被引用数据&#xff0c;供大家研究使用。数据来源原始数据来源于国家统计局&#xff0c;由皮皮侠团队整理计算。…

MySQL知识点(上)

MySQL知识点 一&#xff1a;MySQL概述 MySQL是一款开源的数据库软件&#xff0c;是一种关系型数据库管理系统&#xff08;ROBMS&#xff09;&#xff0c;也叫做表数据库管理系统 如果需要快速安全地处理大量的数据&#xff0c;则必须使用数据库管理系统&#xff1b;任何基于数据…

shell脚本实现sha256sum校验并拷贝校验通过的文件

#!/bin/bash# 目标目录 TARGET_DIR"/appdata/jn1m/versions/old/bin"# 校验文件 CHECKSUM_FILE"checksum.txt"# 检查目标目录是否存在 if [ ! -d "$TARGET_DIR" ]; thenecho "错误&#xff1a;目标目录 $TARGET_DIR 不存在"exit 1 fi#…

中小型泵站物联网智能控制系统解决方案:构建无人值守的自动化泵站体系

一、系统核心架构与功能设计1.物联网感知层设备互联&#xff1a;网关对接压力传感器、超声波液位计、智能电表、振动传感器等&#xff0c;实时采集水泵运行状态&#xff08;流量、压力、温度、振动&#xff09;、液位、水质&#xff08;pH值、浊度&#xff09;、能耗等关键参数…

网络通信---Axios

1、什么是 Axios&#xff1f; Axios​ 是一个基于 ​Promise​ 的 ​HTTP 客户端&#xff0c;用于浏览器和 Node.js 环境&#xff0c;用来发送 ​HTTP 请求&#xff08;如 GET、POST、PUT、DELETE 等&#xff09;​。 它常用于&#xff1a; 向后台 API 发送请求获取数据提交表…

Ubuntu 软件源版本不匹配导致的依赖冲突问题及解决方法

在使用 Ubuntu 系统的过程中&#xff0c;软件包管理是日常操作的重要部分。但有时我们会遇到各种依赖冲突问题&#xff0c;其中软件源与系统版本不匹配是常见且棘手的一种。本文就来详细分享一次因软件源版本不匹配引发的依赖冲突问题&#xff0c;以及具体的解决思路和流程。一…

思考:高速场景的行星轮混动效率如何理解

行星轮混动 E-CVT&#xff08;电子无级变速器&#xff09;是一种专为混合动力汽车设计的动力分配系统&#xff0c;其核心原理是通过行星齿轮组和电机的协同工作&#xff0c;实现动力分流与无级变速。 一、核心结构与组成 E-CVT的核心部件包括 行星齿轮组 和 双电机&#xff08;…

跨域及解决方案

跨域&#xff08;Cross-Origin&#xff09;是指浏览器在执行 JavaScript 的时候&#xff0c;因为同源策略&#xff08;Same-Origin Policy&#xff09;的限制&#xff0c;阻止了一个网页去请求不同源&#xff08;域名、端口、协议有任意一个不同&#xff09;的资源。 1. 什么是…