【Java SE】Arrays工具类

本章将介绍Arrays工具类中的常用方法,主要是操作数组的一些方法。

1.为什么需要学习Arrays工具类

在Java中我们定义一个数组,那么对这个数组的增删改查是不是都需要写相应的方法去实现呢?答案是不需要,因为Java将操作数组的方法封装在了Arrays工具类中,该类在java.util 包中,我们对数组的操作我们只需要导入这个类调用其方法即可。

对比项 原始数组 使用 Arrays 类
排序 需手动实现排序算法 Arrays.sort(arr)
查找 需遍历或自己写二分查找 Arrays.binarySearch(arr, key)
复制 需用 for 循环手动复制 Arrays.copyOf(arr)
比较 需逐个元素比较 Arrays.equals(arr1, arr2)
打印 直接打印得到内存地址 Arrays.toString(arr) 显示内容
填充 需写循环赋值 Arrays.fill(arr, value)

2.Arrays工具类的本质和核心思想

本质:

Arrays 是 Java 专门为操作数组设计的工具类(utility class),它:

  1. 📦 封装数组操作:将开发者常用的数组操作封装成静态方法

  2. ⚙️ 避免重复造轮子:开发者不需要手动实现基础数组算法

  3. 🚀 提供高性能实现:底层使用优化过的算法(如双轴快速排序)

  4. 🧩 补充数组功能:弥补 Java 数组原生功能不足的缺陷

核心:

静态方法工具类

  • 所有方法都是 static

  • 不需要实例化(构造函数私有化)

  • 直接通过类名调用:Arrays.方法名(参数);

3.Arrays中有哪些方法?

在学习Arrays的时候需要查看Java API帮助文档来学习,具体的方法不需要背,多查多用不断地重复自然就记住了,具体的API文档链接如下:

以下是 java.util.Arrays 类中所有核心方法的分类表格总结(基于 Java 17):

一、数组操作核心方法

方法签名 作用 示例
static void sort(primitive[] a) 对基本类型数组升序排序 Arrays.sort(new int[]{3,1,2}) → [1,2,3]
static void sort(Object[] a) 对对象数组按自然顺序排序 Arrays.sort(new String[]{"c","a","b"}) → ["a","b","c"]
static void sort(T[] a, Comparator<? super T> c) 自定义比较器排序 Arrays.sort(users, Comparator.comparing(User::age))
static int binarySearch(primitive[] a, primitive key) 二分查找基本类型数组 Arrays.binarySearch(new int[]{1,2,3}, 2) → 1
static int binarySearch(T[] a, T key, Comparator<? super T> c) 带比较器的二分查找 Arrays.binarySearch(users, keyUser, Comparator.comparing(User::id))
static boolean[] copyOf(boolean[] original, int newLength) 复制数组并调整长度 Arrays.copyOf(new int[]{1,2}, 3) → [1,2,0]
static T[] copyOf(T[] original, int newLength) 复制对象数组 Arrays.copyOf(names, names.length * 2)
static void fill(primitive[] a, primitive val) 填充整个数组 Arrays.fill(arr, -1) → [-1,-1,-1]
static void fill(Object[] a, Object val) 填充对象数组 Arrays.fill(strArr, "empty")
static void fill(primitive[] a, int from, int to, primitive val) 填充指定范围 Arrays.fill(arr, 1, 3, 9) → [0,9,9,0]

二、数组比较与哈希

方法签名 作用 说明
static boolean equals(primitive[] a, primitive[] b) 比较基本类型数组 长度和元素值全等
static boolean equals(Object[] a, Object[] b) 比较对象数组 调用每个元素的 equals()
static boolean deepEquals(Object[] a, Object[] b) 深度比较多维数组 递归比较嵌套数组
static int hashCode(primitive[] a) 计算数组哈希值 基于内容
static int deepHashCode(Object[] a) 深度计算哈希值 适用于嵌套数组

三、数组转字符串

方法签名 作用 示例输出
static String toString(primitive[] a) 一维数组转字符串 "[1, 2, 3]"
static String toString(Object[] a) 对象数组转字符串 "[A, B, C]"
static String deepToString(Object[] a) 多维数组深度转字符串 "[[1, 2], [3, 4]]"

四、Java 8+ 新增方法

方法签名 作用 场景
static void parallelSort(primitive[] a) 并行排序(多核) 大数据量排序
static <T> void parallelSort(T[] a, Comparator<? super T> cmp) 并行对象排序
static void parallelPrefix(primitive[] array, PrimitiveBinaryOperator op) 并行计算前缀 [1,2,3] → [1,3,6](累加)
static void setAll(int[] array, IntUnaryOperator generator) 函数式生成元素 setAll(arr, i -> i*2)
static <T> Spliterator<T> spliterator(T[] array) 获取分割迭代器 流式处理基础
static IntStream stream(int[] array) 生成IntStream流 Arrays.stream(arr).sum()
static <T> Stream<T> stream(T[] array) 生成对象Stream流 Arrays.stream(users).filter(u->u.age>18)

五、特殊操作

方法签名 作用 说明
static List<T> asList(T... a) 数组转固定大小List 注意: 返回的List不支持增删操作
static void parallelSetAll(primitive[] array, IntFunction generator) 并行生成元素 Java 8+
static int mismatch(primitive[] a, primitive[] b) 查找首个不匹配索引 全等返回-1
static int compare(primitive[] a, primitive[] b) 字典序比较数组 类似 String.compareTo()

六、多维数组专用

方法签名 作用 替代方案
static int deepHashCode(Object[] a) 深度哈希计算 替代手动嵌套循环
static boolean deepEquals(Object[] a, Object[] b) 深度比较 替代手动嵌套循环
static String deepToString(Object[] a) 深度转字符串 替代 Arrays.toString() 的嵌套调用

📌 关键说明:

  1. primitive 代表 8 种基本类型:byte/short/int/long/float/double/char/boolean

  2. T 代表引用类型(对象)

  3. 并行方法 (如 parallelSort)适合处理超过 100 万元素的大型数组

  4. 流式方法 (如 stream())需配合 Java 8+ 的 Stream API 使用

  5. asList()陷阱 :返回的 ArrayListArrays 内部类,非 java.util.ArrayList

4.Arrays中常用方法

以下是 Arrays 工具类中常见方法的表格总结及作用说明:

方法名 作用描述 典型使用场景
binarySearch() 已排序的数组中二分查找指定元素,返回索引(找到时)或负数(未找到时) 快速查找有序数组中的元素(时间复杂度 O(log n))
copyOf() 复制原数组并截断或填充到指定长度(新数组长度可大于/小于原数组) 数组扩容、缩容或创建副本
equals() 比较两个一维数组是否内容相等(长度相同且对应位置元素相等) 判断简单数组(非嵌套)是否内容一致
fill() 将指定值填充到数组的所有位置(或指定范围) 数组初始化(如全置0)或重置内容
sort() 对数组进行升序排序(支持基本类型/对象类型),可指定范围或自定义比较规则 数组排序(时间复杂度 O(n log n))
toString() 返回一维数组 的字符串表示(如 [1, 2, 3]),不处理嵌套数组 快速打印一维数组内容(调试输出)
deepToString() 返回多维数组的深层内容字符串(递归处理嵌套数组) 打印多维数组(如 int[][])的实际内容

1.将一维数组转为字符串

Arrays.toString(待操作数组名)

解释:将指定一维数组转为字符串

java 复制代码
import java.util.Arrays;

public class ArraysToString {
    public static void main(String[] args) {
        //定义一个数组
        int[] arr = {1, 2, 3, 4, 5};
        //将数组转为字符串并输出
        String str = Arrays.toString(arr);
        System.out.println(str);
        System.out.println("=============");
        System.out.println(Arrays.toString(arr));
    }
}

2.将二维数组转为字符串

Arrays.deepToString(待操作数组名)

解释:将指定二维数组转为字符串,deep代表深度,说明是将多维数组转为字符串

java 复制代码
import java.util.Arrays;


public class ArraysDeepToString {
    public static void main(String[] args) {
        //定义一个二维数组
        int[][] arrs = {{1,2,3}, {4,5,6,7}, {8,9,10,11,12}};

        //将二维数组转为字符串并输出

        System.out.println(Arrays.deepToString(arrs));
    }
}

3.对数组进行排序

Arrays.sort(待操作数组名)

解释:将待操作数组进行小到大排序

java 复制代码
import java.util.Arrays;

public class ArraysSort {
    public static void main(String[] args) {
        //定义一个数组
        int[] arr = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
        System.out.println("排序前:" + Arrays.toString(arr));
        //使用Arrays中的sort()方法默认是从小到大排序
        Arrays.sort(arr);
        System.out.println("排序后:" + Arrays.toString(arr));
    }
}

4. 在已排序的数组中使用二分查找某个元素

Arrays.binarySearch(待查询数组名,所要查找的值);

Arrays.binarySearch(arr,key);

解释:在arr数组中使用二分查找找出key值如果找到就将他的下标返回

java 复制代码
import java.util.Arrays;

public class ArraysBinarySearch {
    public static void main(String[] args) {
        //定义一个数组
        int[] arr = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
        System.out.println("排序前:" + Arrays.toString(arr));//[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
        //使用Arrays中的sort()方法默认是从小到大排序
        Arrays.sort(arr);
        System.out.println("排序后:" + Arrays.toString(arr));//[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

        //使用二分查找找出元素8
        int tmp = Arrays.binarySearch(arr,8);
        System.out.println("查找出后的值的索引为:" + tmp);
    }
}

5.两个数组中内容的比较

使用的是Arrays.equals方法

反正你记住:比较内容使用的都是equals方法

java 复制代码
public class ArraysEquals {
    public static void main(String[] args){
        int[] arr1 = {1, 2, 3, 4, 5};
        int[] arr2 = {1, 2, 3, 4, 5};
        int[] arr3 = {10, 2, 3, 4, 5};

        System.out.println(Arrays.equals(arr1, arr2));//true
        System.out.println(Arrays.equals(arr1, arr3));//false
        System.out.println(Arrays.equals(arr2, arr3));//false
    }
}

6.在数组中填充给定的值、

使用的是Arrays.fill方法。

fill是充满的意思,在Arrays中改方法用于当不知道或者不想手动对数组赋初值的时候就使用该方法。

java 复制代码
public class ArraysFill {
    public static void main(String[] args) {
        int[] arr = new int[10];
        //将arr所有位置填充10
        Arrays.fill(arr, 10);
        System.out.println(Arrays.toString(arr));//[10, 10, 10, 10, 10, 10, 10, 10, 10, 10]

        //将arr[3, 7)的位置填充上100 实际填充的位置是3,4,5,6  顾前不顾后
        Arrays.fill(arr, 3, 7, 100);
        System.out.println(Arrays.toString(arr));//[10, 10, 10, 100, 100, 100, 100, 10, 10, 10]
        //                                          0    1   2   3    4    5   6    7    8  9
    }

7.拷贝数组

7.1 自定义拷贝数组

什么是拷贝? 所谓的拷贝就是对照着arr数组进行一模一样的复刻从而产生arr长得一模一样的数组copy。

拷贝一定是产生一个新对象的,也就是说必须是重新new一个新数组的。

java 复制代码
public class ArraysCopyOf01 {
    /**
     * 首先 搞清楚什么是拷贝:
     *  所谓的拷贝(复制)
     *   就是说将一个东西 原模原样的复制出新的一份来,那么他必须是产生了新的实体的
     *   所以拷贝自然是需要new出一个新的对象的
     * @param args
     */
    public static void main(String[] args) {
        //定义一个数组
        int[] arr = {1, 2, 3, 35, 45};

        //将拷贝之前的数组arr内容输出
        for (int i: arr) {
            System.out.print(i + " ");
        }
        System.out.println();

        //对arr这个数组进行拷贝
        int[] copy = new int[arr.length];

        //将arr里面数据进行复制在copy中
        for (int i = 0; i < arr.length; i++) {
            copy[i] = arr[i];
        }

        //将拷贝后的数组copy内容输出
        for (int i: copy) {
            System.out.print(i + " ");
        }
        System.out.println();
    }
}

拷贝后的数组的内存图如下:

注意:以下的情况不属于拷贝, 而是属于赋值

java 复制代码
public class ArraysCopyOfTest {
    public static void main(String[] args) {
        //以下情况属于的是赋值,而不是拷贝
        //定义一个数组
        int[] arr = {1, 2, 3, 35, 45};

        //将arr对象的地址赋值给copy变量存起来
        int[] copy = arr;

    }
}

7.2 Arrays.copyOf

数组的拷贝java已经给我们封装好了,拷贝数组的这个方法已经封装在Arrays工具类中了

解释:

Arrays.copyOf(对哪一个数组进行拷贝,拷贝多长);

他的返回值是一个新的数组的,我们到时候使用一个copy数组接收就OK了。

代码如下:

java 复制代码
public class ArraysCopyOf02 {
    public static void main(String[] args) {
        //定义一个数组
        int[] arr = {1, 2, 3, 35, 45};
        //定义一个数字变量 到时候用于接收返回值
        int[] copy;
        //对arr数组进行拷贝并且将返回的数组对象地址使用copy接收
        copy = Arrays.copyOf(arr, arr.length);
        //打印
        System.out.println(Arrays.toString(copy));//[1, 2, 3, 35, 45]
    }
}

copyOf的底层代码分析:

7.3 Arrays.copyOfRange

解释:

copyOfRange 首先Range这个单词是范围的意思,那么顾名思义就是说:这个方法就是对数组进行范围式的拷贝

Arrays.copyOfRange(要拷贝的数组,起点,终点)。

其中:起点和终点是下标 遵循左闭右开原则[起点,终点)(顾前不顾后)

java 复制代码
public class ArraysCopyOf03 {
    public static void main(String[] args) {
        //定义一个数组
        int[] arr = {1, 2, 3, 35, 45};
        //           0  1  2  3   4
        //定义一个数字变量 到时候用于接收返回值
        int[] copy;
        //对arr数组进行拷贝[1,4)并且将返回的数组对象地址使用copy接收
        copy = Arrays.copyOfRange(arr, 1, 4);
        //打印
        System.out.println(Arrays.toString(copy));//[2, 3, 35]
    }
}

copyOfRange底层也是调用了System.arraycopy方法,那么对于该方法的解析是什么呢,请继续往后面看

7.4 System.arraycopy

代码:

java 复制代码
public class ArraysCopyOf04 {
    public static void main(String[] args) {
        // 定义一个数组
        int[] arr = {1, 2, 3, 35, 45};
        //           0  1  2  3   4
        //定义一个copy数组用于存储拷贝后的数据
        int[] copy = new int[arr.length];
        //使用System.arraycopy进行数组的拷贝
        System.arraycopy(arr, 0, copy, 0, arr.length);
        System.out.println(Arrays.toString(arr));//拷贝前arr数组 [1, 2, 3, 35, 45]
        System.out.println(Arrays.toString(copy));//拷贝前copy数组 [1, 2, 3, 35, 45]
    }
}

对该方法的解析

例如:

补充:结合前面所介绍的,数组的拷贝使用Arrays.copyOf和使用System.arraycopy的效率问题:结论是使用System.arraycopy的效率会高一点,原因就是说,由于Arrays.copy底层也是调用System.arraycopy,因此呢,自然没有你直接使用System.arraycopy来得快,当然,现在的话,我是不去纠结该使用哪一个比较好的,他们的效率其实是近似的,二者是差不多的,具体你想使用哪一个方法扩容根据你的需求去处理即可。

7.5 由拷贝引申出的扩容问题

首先什么是扩容?==》扩容有两个特点:将容量变大 和 将原来的数据搬运进去(拷贝进去)。

代码:

java 复制代码
public class CopyOfDilatation {
    public static void main(String[] args) {
        //定义一个arr数组
        int[] arr = {1, 3, 4, 7, 10};

        //首先将对arr进行拷贝
        int[] copy = Arrays.copyOf(arr, arr.length*2);

        //最后将copy所指向的地址给arr 从而实现扩容
        arr = copy;

        //将arr打印
        System.out.println(Arrays.toString(arr));//[1, 3, 4, 7, 10, 0, 0, 0, 0, 0]
    }

细节分析:

内存图如下:

相关推荐
JosieBook8 分钟前
【Java编程动手学】深入剖析Java网络编程:原理、协议与应用
java·udp·tcp
black_blank8 分钟前
st表 && csp37 第四题 集体锻炼
java·数据结构·算法
默凉10 分钟前
C++ 虚函数(多态,多重继承,菱形继承)
开发语言·c++
我爱Jack11 分钟前
Java List 使用详解:从入门到精通
java·开发语言·数据结构
-凌凌漆-17 分钟前
【Qt】Qt QML json处理
开发语言·qt·json
手握风云-18 分钟前
JavaEE初阶第八期:解锁多线程,从 “单车道” 到 “高速公路” 的编程升级(六)
java·开发语言
天南星31 分钟前
java-WebSocket在Java生态中的发展历程
java·后端·websocket
chuanauc1 小时前
记录一次在 centos 虚拟机 中 安装 Java环境
java·linux·centos
楼田莉子1 小时前
数据学习之队列
c语言·开发语言·数据结构·学习·算法
写不出来就跑路1 小时前
SpringBoot静态资源与缓存配置全解析
java·开发语言·spring boot·spring·springboot