《Java 100 天进阶之路》第32篇:Java常用工具类(Objects、Collections、Arrays深入)

第32篇:Java常用工具类(Objects、Collections、Arrays深入)

📌 系列导航《Java 100 天进阶之路》完整目录 |

⬅️ 上一篇:第31篇:Java数组详解 |

➡️ 下一篇:第33篇:Java中的static关键字详解


一、核心知识点

  • java.util.Objects 类:null 安全的方法(equalshashCodetoStringrequireNonNullisNull 等)
  • java.util.Collections 类:集合的操作(排序、混排、不可变集合、同步包装器)
  • java.util.Arrays 类:数组的操作(排序、二分查找、填充、拷贝、转 List)
  • java.util.ComparableComparator:对象的排序

二、通俗讲解(1分钟开心学)

1. Objects 工具类

Java 7 引入,专门处理可能为 null 的对象,避免手动写 if (obj != null)。例如 Objects.equals(a, b) 会在 a 和 b 都为 null 时返回 true,其中一个 null 时返回 false,比 a.equals(b) 安全。

2. Collections 工具类

操作 CollectionMap 的静态方法:

  • sort(List<T>):排序(要求元素实现 Comparable
  • reverse(List):反转
  • shuffle(List):随机打乱
  • unmodifiableList(List):返回只读视图
  • synchronizedList(List):返回线程安全的包装

3. Arrays 工具类

操作数组的静态方法:

  • sort()binarySearch()fill()copyOf()equals()
  • asList():将数组转成 List(注意返回的是固定大小的 Arrays.ArrayList

4. 排序比较器

  • 对象自然排序:实现 Comparable<T> 接口,重写 compareTo
  • 定制排序:实现 Comparator<T> 接口,重写 compare

生活类比Objects 就像安全扶手,防止你在 null 上摔跤。CollectionsArrays 就像瑞士军刀,给集合和数组提供各种常用工具。

三、实操代码案例 + 场景说明

场景:对员工列表进行多种排序(按姓名、按工资),并确保集合不可修改。

java 复制代码
import java.util.*;
import java.util.stream.Collectors;

class Employee implements Comparable<Employee> {
    private String name;
    private double salary;
    
    public Employee(String name, double salary) {
        this.name = name;
        this.salary = salary;
    }
    
    public String getName() { return name; }
    public double getSalary() { return salary; }
    
    // 自然排序:按姓名
    @Override
    public int compareTo(Employee o) {
        return this.name.compareTo(o.name);
    }
    
    @Override
    public String toString() {
        return String.format("%s(%.0f)", name, salary);
    }
    
    // 静态工厂方法用于创建 Comparator
    public static Comparator<Employee> byName = Comparator.comparing(Employee::getName);
    public static Comparator<Employee> bySalary = Comparator.comparingDouble(Employee::getSalary);
}

public class UtilsDemo {
    public static void main(String[] args) {
        // 1. Objects 工具类
        String s1 = null;
        String s2 = "hello";
        System.out.println(Objects.equals(s1, s2));      // false
        System.out.println(Objects.hashCode(s1));        // 0
        System.out.println(Objects.toString(s1, "默认")); // 默认
        Objects.requireNonNull(s2, "s2 不能为 null");     // 不抛异常
        // Objects.requireNonNull(s1, "s1 不能为 null"); // 会抛 NPE
        
        // 2. Collections 与 Arrays
        List<Integer> list = new ArrayList<>(Arrays.asList(3, 1, 4, 1, 5));
        Collections.sort(list);
        System.out.println(list);   // [1,1,3,4,5]
        Collections.reverse(list);
        System.out.println(list);   // [5,4,3,1,1]
        Collections.shuffle(list);
        System.out.println("随机:" + list);
        
        // 不可变集合
        List<Integer> unmod = Collections.unmodifiableList(list);
        // unmod.add(10); // 抛 UnsupportedOperationException
        
        // 3. 数组工具
        int[] arr = {5,2,8,1};
        Arrays.sort(arr);
        System.out.println(Arrays.toString(arr));
        int index = Arrays.binarySearch(arr, 8);
        System.out.println("8的位置:" + index);
        int[] copy = Arrays.copyOf(arr, 10);
        System.out.println("拷贝并扩容:" + Arrays.toString(copy));
        
        // 4. 员工排序
        List<Employee> employees = Arrays.asList(
            new Employee("Bob", 5000),
            new Employee("Alice", 7000),
            new Employee("Charlie", 6000)
        );
        // 按姓名排序
        employees.sort(Employee.byName);
        System.out.println("按姓名:" + employees);
        // 按工资排序
        employees.sort(Employee.bySalary);
        System.out.println("按工资:" + employees);
        // 链式排序:先按工资,再按姓名
        employees.sort(Employee.bySalary.thenComparing(Employee.byName));
    }
}

四、避坑要点

错误/误区 后果 正确做法
Arrays.asList(arr) 返回的 List 调用 add/remove UnsupportedOperationException new ArrayList<>(Arrays.asList(arr))
修改 Collections.unmodifiableXxx 返回的集合 抛异常 不要尝试修改,或先拷贝再修改
Objects.equals(a, b)a.equals(b) 混淆 前者 null 安全,后者可能 NPE 不确定是否为 null 时用 Objects.equals
自定义 Comparator 时未处理 null 可能 NPE 使用 Comparator.nullsFirstnullsLast

五、面试高频考点

Q1:Objects.equals(a, b)a.equals(b) 的区别?

Objects.equals 是 null 安全的,两个都为 null 返回 true,一个为 null 返回 false,否则调用 a.equals(b)。后者在 a 为 null 时抛 NPE。

Q2:Collections.sort(list)list.sort(null) 的区别?

功能相同,list.sort(null)List 接口的默认方法(Java 8 引入),可以直接被集合调用。Collections.sort 是旧 API,内部调用了 list.sort

Q3:如何将数组转换成可变的 ArrayList

new ArrayList<>(Arrays.asList(arr))

六、练习题

  1. 填空 :使用 Objects.requireNonNull 替代手动 null 检查。
  2. 排序:对一组字符串按长度排序,长度相同再按字典序。
  3. 动手 :实现一个 Comparator<Person>,先按年龄降序,再按姓名升序。

📊 你的学习进度

  • 当前:第32篇 / 共44篇 · 第五阶段:工具类、异常最佳实践、序列化(第32~35篇)
  • ✅ 已完成:第1~31篇
  • 📖 正在学:第32篇
  • ⏳ 待学习:第33~44篇

👉 📚 完整目录 & 学习指南 | 🔥 订阅本专栏,不错过每一篇

💡 本专栏每篇都包含:避坑表 + 面试高频考点 + 练习题。每天30分钟,100天拿offer!


👉 下一篇文章预告

《第33篇:Java中的static关键字详解》

内容简介:静态变量/方法/代码块,内存位置(方法区),静态导入,静态方法的重写问题。

💡 学完这篇,你将彻底掌握static的语义,面试再问静态成员轻松回答。

📌 《Java 100 天进阶之路 | 从入门到上岗就业》 每天一篇,建议收藏 + 关注 ,一起100天拿offer!

👉 点击关注我,更新后第一时间收到推送!

相关推荐
我是一颗柠檬15 小时前
【Java项目技术亮点】Redis Lua脚本原子化操作:高并发场景下的终极武器
java·redis·lua
swg32132115 小时前
Redis实现主从选举
java·前端·redis
砍材农夫15 小时前
python环境|pip|uv|venv|Conda区别
后端·python·conda·pip·uv
Java 码思客15 小时前
【ElasticSearch 从入门到架构师】第6章_分词器与文本检索
java·elasticsearch
Flittly15 小时前
【AgentScope Java新手村系列】(6)Hook与Middleware
java·spring boot·笔记·spring·ai
向量引擎15 小时前
AI API 正在进入“请求生命周期治理”阶段:从模型迁移、Agent 接入到成本与安全排错的工程化方法
java·人工智能·python·aigc·ai编程·ai写作·gpu算力
牛油果子哥q15 小时前
二叉树(Binary Tree)零基础精讲,树基础概念、树形分类、核心性质、递归/层序遍历、完整代码与面试考点全解
c++·面试·数据挖掘
Csvn15 小时前
Linux 网络配置与排查命令实战
后端
许彰午15 小时前
34_Java设计模式之单例模式
java·单例模式·设计模式
摇滚侠15 小时前
MyBatis 入门到项目实战 IDEA 配置模板 20-22
java·intellij-idea·mybatis