当前位置: 首页 > news >正文

Java 工具类详解:Arrays、Collections、Objects 一篇通关

在 Java 开发中,数组、集合和对象是我们每天都会打交道的核心元素。为了简化这些元素的操作,JDK 提供了三个超实用的工具类:Arrays(数组操作)、Collections(集合操作)、Objects(对象工具)。它们就像 "瑞士军刀",封装了大量常用功能,能帮我们少写几百行代码。今天就带大家深入剖析这三个工具类的核心用法、底层逻辑和避坑指南,配上直观图解,让你一次掌握!

一、Arrays:数组操作的 "全能助手"

数组是 Java 中最基础的数据结构,但原生数组的操作(排序、查找、复制等)并不方便。java.util.Arrays类专门为数组提供了一系列静态方法,让数组操作变得简单高效。

1. 核心功能:排序、查找、填充、复制

(1)排序:sort()—— 让数组有序化

Arrays.sort()支持对各种类型的数组进行排序,底层根据数组类型选择不同算法(基本类型用双轴快速排序,对象类型用 TimSort)。

// 基本类型数组排序
int[] nums = {3, 1, 4, 1, 5};
Arrays.sort(nums);  // 排序后:[1, 1, 3, 4, 5]// 对象数组排序(需实现Comparable或传入Comparator)
String[] strs = {"apple", "banana", "cherry"};
Arrays.sort(strs);  // 按自然顺序排序:[apple, banana, cherry]// 指定范围排序(从索引1到4,左闭右开)
int[] arr = {5, 3, 8, 2, 7};
Arrays.sort(arr, 1, 4);  // 排序后:[5, 2, 3, 8, 7]
(2)查找:binarySearch()—— 快速定位元素

二分查找必须在已排序的数组中使用,返回元素索引(未找到则返回负数)。

int[] nums = {1, 3, 5, 7, 9};
int index = Arrays.binarySearch(nums, 5);  // 返回2(找到)
int notFound = Arrays.binarySearch(nums, 4);  // 返回-3(未找到,插入点为2)
(3)填充:fill()—— 批量设置元素值

快速将数组的指定范围填充为同一个值,适合初始化数组。

int[] arr = new int[5];
Arrays.fill(arr, 10);  // 全部填充10:[10, 10, 10, 10, 10]// 填充指定范围
Arrays.fill(arr, 1, 3, 20);  // 索引1-2填充20:[10, 20, 20, 10, 10]
(4)复制:copyOf()arraycopy()—— 数组克隆与截取
  • copyOf():从原数组开头复制指定长度(新数组长度可大于原数组,多余部分补默认值)。
  • arraycopy():从原数组指定位置复制到目标数组(更灵活,需手动创建目标数组)。
int[] original = {1, 2, 3, 4, 5};// copyOf:复制前3个元素
int[] copy1 = Arrays.copyOf(original, 3);  // [1, 2, 3]// arraycopy:从原数组索引1复制2个元素到目标数组索引0
int[] copy2 = new int[2];
System.arraycopy(original, 1, copy2, 0, 2);  // copy2:[2, 3]

2. 实用功能:数组转集合与内容比较

(1)asList():数组转 List 集合

将数组转换为List,但注意:返回的是Arrays.ArrayList(Arrays 的内部类),不支持添加 / 删除元素(会抛UnsupportedOperationException)。

String[] strs = {"a", "b", "c"};
List<String> list = Arrays.asList(strs);list.set(0, "x");  // 支持修改元素
// list.add("d");  // 报错:UnsupportedOperationException

坑点:如果传入基本类型数组asList()会将整个数组当作一个元素(因为泛型不支持基本类型)。例如int[]转 List 会得到List<int[]>,而非List<Integer>。解决办法:用包装类数组(Integer[])。

(2)equals()deepEquals():数组内容比较
  • equals():比较一维数组的元素是否完全相同(基本类型比较值,对象比较引用)。
  • deepEquals():用于多维数组比较(递归比较嵌套数组的内容)。
int[] a = {1, 2};
int[] b = {1, 2};
System.out.println(Arrays.equals(a, b));  // true(内容相同)int[][] c = {{1, 2}, {3, 4}};
int[][] d = {{1, 2}, {3, 4}};
System.out.println(Arrays.equals(c, d));  // false(二维数组用equals比较引用)
System.out.println(Arrays.deepEquals(c, d));  // true(深层比较内容)

3. Arrays 功能图解

二、Collections:集合操作的 "瑞士军刀"

java.util.Collections是针对集合框架(List、Set、Map)的工具类,提供了排序、查找、同步控制、不可变集合等实用功能,与Arrays遥相呼应。

1. 核心功能:排序、查找、反转

(1)排序:sort()——List 排序神器

Arrays.sort()类似,但专门用于List集合,支持自然排序和自定义比较器。

List<Integer> list = new ArrayList<>(Arrays.asList(3, 1, 4));
Collections.sort(list);  // 自然排序:[1, 3, 4]// 自定义比较器(降序)
Collections.sort(list, (a, b) -> b - a);  // [4, 3, 1]
(2)查找:binarySearch()indexOfSubList()
  • binarySearch():在已排序的 List 中查找元素(同 Arrays,依赖排序)。
  • indexOfSubList():查找子列表在父列表中的起始索引(未找到返回 - 1)。
List<String> list = Arrays.asList("a", "b", "c", "d");
int index = Collections.binarySearch(list, "c");  // 返回2List<String> subList = Arrays.asList("b", "c");
int subIndex = Collections.indexOfSubList(list, subList);  // 返回1(子列表从索引1开始)
(3)反转与打乱:reverse()shuffle()
  • reverse():反转 List 中元素的顺序。
  • shuffle():随机打乱元素顺序(适合洗牌、随机抽样场景)。
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4));
Collections.reverse(list);  // [4, 3, 2, 1]Collections.shuffle(list);  // 随机顺序,如[2, 4, 1, 3]

2. 进阶功能:同步集合与不可变集合

(1)同步集合:synchronizedXxx()—— 线程安全的集合

为非线程安全的集合(如 ArrayList、HashMap)生成线程安全的版本(通过包装器实现,底层用synchronized加锁)。

// 创建线程安全的List
List<String> syncList = Collections.synchronizedList(new ArrayList<>());
// 创建线程安全的Map
Map<String, Integer> syncMap = Collections.synchronizedMap(new HashMap<>());

注意:同步集合是 "粗粒度" 锁,性能较低,高并发场景建议用java.util.concurrent包下的并发集合(如 ConcurrentHashMap)。

(2)不可变集合:unmodifiableXxx()—— 只读集合

创建不可修改的集合(禁止添加、删除、修改元素),适合保护数据不被篡改。

List<String> original = new ArrayList<>(Arrays.asList("a", "b"));
List<String> unmodifiable = Collections.unmodifiableList(original);// unmodifiable.add("c");  // 报错:UnsupportedOperationException
original.add("c");  // 原集合修改,不可变集合也会同步变化(注意!)

更彻底的不可变集合:用List.of()(Java 9+),原集合修改不影响不可变集合,且性能更好。

3. 其他实用方法

  • fill(list, obj):用指定对象填充 List(覆盖所有元素)。
  • max(collection)/min(collection):获取集合中的最大 / 小元素(依赖排序)。
  • frequency(collection, obj):统计元素在集合中出现的次数。
  • swap(list, i, j):交换 List 中两个索引的元素。

4. Collections 功能图解

三、Objects:对象操作的 "安全卫士"

java.util.Objects(Java 7+)是处理对象的工具类,封装了对象的比较、空值判断、哈希计算等常用操作,尤其擅长避免NullPointerException(空指针异常)。

1. 核心功能:空值处理与对象比较

(1)空值判断:isNull()nonNull()

简化null判断,比obj == null更直观。

String str = null;
System.out.println(Objects.isNull(str));  // true(是否为null)
System.out.println(Objects.nonNull(str));  // false(是否不为null)
(2)非空校验:requireNonNull()—— 快速失败

在方法入参校验时使用,若对象为null则立即抛出NullPointerException,避免后续逻辑出错。

public void process(String str) {// 校验参数非空,为空则抛异常Objects.requireNonNull(str, "参数str不能为null");// 后续逻辑...
}
(3)对象比较:equals()deepEquals()
  • equals(a, b):安全比较两个对象是否相等(避免a.equals(b)anull的问题)。
  • deepEquals(a, b):深度比较(适合数组或对象引用的嵌套结构)。
String a = "hello";
String b = "hello";
String c = null;// 安全比较,避免空指针
System.out.println(Objects.equals(a, b));  // true
System.out.println(Objects.equals(a, c));  // false(c为null时不报错)// 深度比较数组
int[] arr1 = {1, 2};
int[] arr2 = {1, 2};
System.out.println(Objects.equals(arr1, arr2));  // false(数组引用不同)
System.out.println(Objects.deepEquals(arr1, arr2));  // true(内容相同)

2. 其他实用方法

  • hash(obj...):计算多个对象的哈希值(比手动计算更方便,支持可变参数)。
    int hash = Objects.hash("a", 123, true);  // 组合哈希值
    
  • toString(obj):安全获取对象的字符串表示(对象为null时返回 "null",而非抛异常)。
    String str = null;
    System.out.println(Objects.toString(str));  // "null"
    System.out.println(Objects.toString(str, "默认值"));  // "默认值"(自定义null时的返回值)
    
  • compare(a, b, comparator):使用比较器比较两个对象(支持null,默认null小于非 null)。

3. Objects 功能图解

四、总结:三大工具类的核心价值

工具类核心场景最常用方法避坑要点
Arrays数组排序、查找、复制sort()binarySearch()copyOf()asList()返回的 List 不可修改;基本类型数组转集合需用包装类
Collections集合排序、同步、不可变sort()synchronizedList()reverse()同步集合性能低,高并发用并发集合;不可变集合依赖原集合
Objects对象空值处理、比较isNull()equals()requireNonNull()equals()deepEquals()的区别;toString()的 null 安全

这三个工具类的设计思想是 "封装共性操作,减少重复代码"。熟练掌握它们,不仅能提升开发效率,还能避免手动实现时的潜在 bug(如空指针、排序算法错误)。记住:JDK 自带的工具类往往经过了充分优化和测试,优先使用它们,而不是重复造轮子!

最后,建议大家多翻 JDK 源码(比如Arrays.sort()的实现、Objects.equals()的空值处理逻辑),深入理解底层原理,才能真正做到灵活运用。


版权声明:本博客内容为原创,转载请保留原文链接及作者信息。

http://www.dtcms.com/a/461582.html

相关文章:

  • Cucumber自学导航
  • docker案例
  • 网站如何做提现功能上海市城乡和住房建设厅网站
  • 南宁 网站建设 公司老吕爱分享 wordpress
  • python 矩阵中寻找就接近的目标值 (矩阵-中等)含源码(八)
  • 嵌入式Linux:线程中信号处理
  • docker启动容器慢,很慢,特别慢的坑
  • C#基础14-非泛型集合
  • 【22.1-决策树的构建1】
  • asp制作网站wordpress使用端口
  • 【机器学习】(一)实用入门指南——如何快速搭建自己的模型
  • 【数值分析】插值法实验
  • 地方门户网站的前途搜索引擎大全全搜网
  • 如何给oracle新建架构(schema)
  • 天地数码携手一半科技PLM 赋能应对全球市场,升级热转印色带研发能力
  • 构筑智能防线:大视码垛机如何重新定义工业安全新标准
  • iPhone17实体卡槽消失?eSIM 普及下的安全挑战与应对
  • 什么RPA可以生成EXE
  • 网站开发设计jw100交换链接的作用
  • 企业推广网站建设报价吉林网站建站系统平台
  • 热壁MOCVD有助于GaN-on-AlN HEMT
  • 网站app微信三合一怎么看网站后台什么语言做的
  • 【深度学习新浪潮】大模型推理实战:模型切分核心技术(上)—— 张量并行原理+国内开源案例+踩坑点
  • 高效SQLite操作:基于C++模板元编程的自动化封装
  • uniApp App内嵌H5打开内部链接,返回手势(左滑右滑页面)会直接关闭H5项目
  • 文字排版网站网站建设的宣传词
  • K8s学习笔记(十七) pod优雅终止流程
  • Redis-基础介绍
  • Redis常用数据库及单线程模式
  • Subword-Based Tokenization策略之BPE与BBPE