首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Apache Commons Lang ArrayUtils:一图看懂 Java 数组操作 12 类核心能力

Apache Commons Lang ArrayUtils:一图看懂 Java 数组操作 12 类核心能力

作者头像
DevLlama
发布2026-06-08 09:59:11
发布2026-06-08 09:59:11
30
举报

ArrayUtils 是 Apache Commons Lang 中用于处理数组的工具类。它把 Java 数组中常见但繁琐的操作封装成了一组 public static 方法,适合用于数组创建、查询、修改、转换、判空、排序判断等场景。

本文基于 Apache Commons Lang ArrayUtils 3.20.0,对其能力按功能分类进行整理。文中的示例来自 ArrayUtilsTest 中的代表性测试用例。

一、整体能力概览

从功能上看,ArrayUtils 主要覆盖以下 12 类能力:

  1. 1. 常量类能力
  2. 2. 添加、合并、插入
  3. 3. 删除元素
  4. 4. 查找和包含判断
  5. 5. 获取元素、长度和类型
  6. 6. 判空、比较和排序判断
  7. 7. 克隆、切片和复制
  8. 8. null 处理
  9. 9. 顺序调整
  10. 10. 批量设置
  11. 11. 类型转换
  12. 12. 字符串、哈希值和 Map 表示

按唯一方法名统计,ArrayUtils 共有 44 个 public static 方法名。需要注意的是,这里统计的是唯一方法名,不是全部重载。由于 ArrayUtils 对基本类型数组、包装类型数组、对象数组都提供了大量重载,实际 public static 重载数量远多于唯一方法名。

二、常量类能力

1. 空数组常量

ArrayUtils 提供了大量空数组常量,用于复用空数组对象,避免重复创建 new int[0]new String[0] 这类对象。

常见常量包括:

  • EMPTY_BOOLEAN_ARRAY
  • EMPTY_BYTE_ARRAY
  • EMPTY_CHAR_ARRAY
  • EMPTY_DOUBLE_ARRAY
  • EMPTY_FLOAT_ARRAY
  • EMPTY_INT_ARRAY
  • EMPTY_LONG_ARRAY
  • EMPTY_SHORT_ARRAY
  • EMPTY_OBJECT_ARRAY

这些常量适合在方法返回空结果时使用。例如,当一个方法需要返回空数组而不是 null 时,可以直接返回对应的 EMPTY_*_ARRAY

代码语言:javascript
复制
assertNotNull(ArrayUtils.EMPTY_BOOLEAN_ARRAY);
assertEquals(0, ArrayUtils.EMPTY_BOOLEAN_ARRAY.length);
assertNotNull(ArrayUtils.EMPTY_BYTE_ARRAY);
assertEquals(0, ArrayUtils.EMPTY_BYTE_ARRAY.length);
assertNotNull(ArrayUtils.EMPTY_CHAR_ARRAY);
assertEquals(0, ArrayUtils.EMPTY_CHAR_ARRAY.length);
assertNotNull(ArrayUtils.EMPTY_DOUBLE_ARRAY);
assertEquals(0, ArrayUtils.EMPTY_DOUBLE_ARRAY.length);
assertNotNull(ArrayUtils.EMPTY_FLOAT_ARRAY);
assertEquals(0, ArrayUtils.EMPTY_FLOAT_ARRAY.length);
assertNotNull(ArrayUtils.EMPTY_INT_ARRAY);
assertEquals(0, ArrayUtils.EMPTY_INT_ARRAY.length);
assertNotNull(ArrayUtils.EMPTY_LONG_ARRAY);
assertEquals(0, ArrayUtils.EMPTY_LONG_ARRAY.length);
assertNotNull(ArrayUtils.EMPTY_SHORT_ARRAY);
assertEquals(0, ArrayUtils.EMPTY_SHORT_ARRAY.length);
assertNotNull(ArrayUtils.EMPTY_OBJECT_ARRAY);
assertEquals(0, ArrayUtils.EMPTY_OBJECT_ARRAY.length);

2. INDEX_NOT_FOUND

INDEX_NOT_FOUND 的值固定为 -1,用于表示查找失败。

它常见于 indexOflastIndexOf 等查找方法的返回值中,语义类似 String.indexOf 返回 -1

代码语言:javascript
复制
assertEquals(-1, ArrayUtils.INDEX_NOT_FOUND);

三、添加、合并、插入

这一类方法用于基于原数组创建新数组,并向其中添加一个或多个元素。

1. add

add 用于复制原数组,并在末尾或指定位置添加一个元素。

典型使用场景:

  • • 在数组末尾追加元素
  • • 在指定索引位置插入元素
  • • 对 null 数组添加元素,得到一个单元素数组
代码语言:javascript
复制
int[] result = ArrayUtils.add(new int[]{1}, 2);
assertArrayEquals(new int[]{1, 2}, result);

result = ArrayUtils.add((int[]) null, 1);
assertArrayEquals(new int[]{1}, result);

2. addFirst

addFirst 用于复制数组,并在数组开头添加一个元素。

代码语言:javascript
复制
final int[] array = new int[]{1, 2};
final int[] result = ArrayUtils.addFirst(array, 0);

assertArrayEquals(new int[]{0, 1, 2}, result);

3. addAll

addAll 用于合并两个数组。

典型使用场景:

  • • 拼接两个基本类型数组
  • • 拼接两个对象数组
  • • 处理其中一个数组为 null 的情况
代码语言:javascript
复制
final int[] array1 = new int[]{1, 2};
final int[] array2 = new int[]{3};

int[] result = ArrayUtils.addAll(array1, array2);
assertArrayEquals(new int[]{1, 2, 3}, result);

result = ArrayUtils.addAll(null, array2);
assertArrayEquals(array2, result);

result = ArrayUtils.addAll(array1, (int[]) null);
assertArrayEquals(array1, result);

4. insert

insert 用于在指定索引位置插入一个或多个元素。

它和 add(array, index, element) 的区别在于:

  • add 更偏向插入单个元素
  • insert 更偏向批量插入多个值
代码语言:javascript
复制
final int[] array = new int[]{1, 3};
final int[] result = ArrayUtils.insert(1, array, 2);

assertArrayEquals(new int[]{1, 2, 3}, result);

四、删除元素

这一类方法用于从数组中删除指定元素或指定索引,并返回删除后的新数组。

1. remove

remove 用于删除指定索引位置的元素。

代码语言:javascript
复制
final int[] array = new int[]{1, 2, 3};
final int[] result = ArrayUtils.remove(array, 1);

assertArrayEquals(new int[]{1, 3}, result);

2. removeAll

removeAll 用于删除多个指定索引位置的元素。

代码语言:javascript
复制
final int[] array = new int[]{1, 2, 3, 4};
final int[] result = ArrayUtils.removeAll(array, 1, 3);

assertArrayEquals(new int[]{1, 3}, result);

3. removeElement

removeElement 用于删除第一个匹配的元素。

如果数组中存在多个相同元素,它只删除第一次出现的那个。

代码语言:javascript
复制
final int[] array = new int[]{1, 2, 2, 3};
final int[] result = ArrayUtils.removeElement(array, 2);

assertArrayEquals(new int[]{1, 2, 3}, result);

4. removeElements

removeElements 用于按给定元素删除对应匹配项。

它不是简单地删除所有匹配元素,而是按照传入元素的数量进行删除。

代码语言:javascript
复制
final int[] array = new int[]{1, 2, 2, 3, 3};
final int[] result = ArrayUtils.removeElements(array, 2, 3);

assertArrayEquals(new int[]{1, 2, 3}, result);

5. removeAllOccurrences

removeAllOccurrences 用于删除数组中所有匹配的元素。

代码语言:javascript
复制
final int[] array = new int[]{1, 2, 2, 3};
final int[] result = ArrayUtils.removeAllOccurrences(array, 2);

assertArrayEquals(new int[]{1, 3}, result);

6. removeAllOccurences

removeAllOccurencesremoveAllOccurrences 的旧拼写兼容方法。

注意:Occurences 少了一个 r。它的语义与 removeAllOccurrences 相同,主要用于兼容旧代码。

代码语言:javascript
复制
final int[] array = new int[]{1, 2, 2, 3};
final int[] result = ArrayUtils.removeAllOccurences(array, 2);

assertArrayEquals(new int[]{1, 3}, result);

五、查找和包含判断

这一类方法用于判断元素是否存在,以及查找元素出现的位置。

1. contains

contains 用于判断数组是否包含指定元素。

代码语言:javascript
复制
final int[] array = new int[]{1, 2, 3};

assertTrue(ArrayUtils.contains(array, 2));
assertFalse(ArrayUtils.contains(array, 5));
assertFalse(ArrayUtils.contains((int[]) null, 1));

2. containsAny

containsAny 用于判断数组是否包含任意一个给定元素。

代码语言:javascript
复制
final int[] array = new int[]{1, 2, 3};

assertTrue(ArrayUtils.containsAny(array, 1, 5));
assertFalse(ArrayUtils.containsAny(array, 4, 5));

3. indexOf

indexOf 用于查找元素第一次出现的位置。

部分重载支持指定起始索引。

代码语言:javascript
复制
final int[] array = new int[]{1, 2, 3, 2};

assertEquals(0, ArrayUtils.indexOf(array, 1));
assertEquals(1, ArrayUtils.indexOf(array, 2));
assertEquals(-1, ArrayUtils.indexOf(array, 5));

4. lastIndexOf

lastIndexOf 用于查找元素最后一次出现的位置。

部分重载支持从指定位置向前查找。

代码语言:javascript
复制
final int[] array = new int[]{1, 2, 3, 2};

assertEquals(3, ArrayUtils.lastIndexOf(array, 2));
assertEquals(-1, ArrayUtils.lastIndexOf(array, 5));

5. indexesOf

indexesOf 用于查找元素出现的所有位置,并返回 BitSet

它适合需要一次获取全部匹配索引的场景。

代码语言:javascript
复制
final int[] array = new int[]{1, 2, 3, 2};
final BitSet result = ArrayUtils.indexesOf(array, 2);

assertTrue(result.get(1));
assertTrue(result.get(3));
assertEquals(2, result.cardinality());

6. startsWith

startsWith 用于判断一个 byte[] 是否以另一个 byte[] 作为前缀。

代码语言:javascript
复制
final byte[] data = new byte[]{1, 2, 3};

assertTrue(ArrayUtils.startsWith(data, new byte[]{1, 2}));
assertFalse(ArrayUtils.startsWith(data, new byte[]{2, 3}));

六、获取元素、长度和类型

这一类方法用于读取数组中的元素信息、长度信息和类型信息。

1. get

get 用于按索引获取数组元素。

常见语义:

  • • 索引有效时返回对应元素
  • • 索引越界时返回 null 或指定默认值
代码语言:javascript
复制
final String[] array = new String[]{"a", "b", "c"};

assertEquals("a", ArrayUtils.get(array, 0));
assertEquals("c", ArrayUtils.get(array, 2));
assertNull(ArrayUtils.get(array, 5));

2. getLength

getLength 用于获取数组长度。

如果输入为 null,返回 0

代码语言:javascript
复制
final int[] array = new int[]{1, 2};

assertEquals(2, ArrayUtils.getLength(array));
assertEquals(0, ArrayUtils.getLength(null));

3. getComponentType

getComponentType 用于获取数组的组件类型。

代码语言:javascript
复制
final String[] array = new String[]{"a", "b"};

assertEquals(String.class, ArrayUtils.getComponentType(array));

4. newInstance

newInstance 用于根据组件类型和长度创建新数组。

代码语言:javascript
复制
final String[] result = ArrayUtils.newInstance(String.class, 2);
assertEquals(2, result.length);

assertEquals(String.class, result.getClass().getComponentType());

七、判空、比较和排序判断

这一类方法用于判断数组是否为空、长度是否一致、类型是否一致、内容是否相等,以及是否有序。

1. isEmpty

isEmpty 用于判断数组是否为 null 或长度为 0

代码语言:javascript
复制
assertTrue(ArrayUtils.isEmpty((Object[]) null));
assertTrue(ArrayUtils.isEmpty(new int[0]));
assertFalse(ArrayUtils.isEmpty(new int[]{1}));

2. isNotEmpty

isNotEmpty 用于判断数组是否非 null 且长度大于 0

代码语言:javascript
复制
assertFalse(ArrayUtils.isNotEmpty((Object[]) null));
assertFalse(ArrayUtils.isNotEmpty(new int[0]));
assertTrue(ArrayUtils.isNotEmpty(new int[]{1}));

3. isSameLength

isSameLength 用于判断两个数组长度是否相同。

代码语言:javascript
复制
final int[] array1 = new int[]{1, 2};
final int[] array2 = new int[]{3, 4};

assertTrue(ArrayUtils.isSameLength(array1, array2));
assertFalse(ArrayUtils.isSameLength(array1, new int[]{1}));

4. isSameType

isSameType 用于判断两个数组类型是否相同。

代码语言:javascript
复制
final int[] array1 = new int[]{1, 2};
final int[] array2 = new int[]{3, 4};

assertTrue(ArrayUtils.isSameType(array1, array2));

5. isEquals

isEquals 用于判断两个数组内容是否相等。

该方法在当前版本中已标记为 deprecated,但仍可用于理解历史 API。

代码语言:javascript
复制
final int[] array1 = new int[]{1, 2};
final int[] array2 = new int[]{1, 2};

assertTrue(ArrayUtils.isEquals(array1, array2));

6. isSorted

isSorted 用于判断数组是否已经排序。

常见重载包括:

  • • 使用自然顺序判断
  • • 使用自定义 Comparator 判断
代码语言:javascript
复制
final int[] sorted = new int[]{1, 2, 3};
final int[] unsorted = new int[]{3, 1, 2};

assertTrue(ArrayUtils.isSorted(sorted));
assertFalse(ArrayUtils.isSorted(unsorted));

7. isArrayIndexValid

isArrayIndexValid 用于判断索引是否是数组的有效索引。

有效索引满足:

代码语言:javascript
复制
0 <= index < array.length

测试中可以看到,null 数组不会拥有有效索引:

代码语言:javascript
复制
final String[] array = new String[]{"a", "b"};

assertTrue(ArrayUtils.isArrayIndexValid(array, 0));
assertTrue(ArrayUtils.isArrayIndexValid(array, 1));
assertFalse(ArrayUtils.isArrayIndexValid(array, 2));
assertFalse(ArrayUtils.isArrayIndexValid(null, 0));

八、克隆、切片和复制

这一类方法用于创建数组副本,或复制数组中的一段内容。

1. clone

clone 用于克隆数组。

语义:

  • • 非 null 数组返回内容相同但引用不同的新数组
  • null 输入返回 null
代码语言:javascript
复制
final int[] array = new int[]{1, 2};
final int[] result = ArrayUtils.clone(array);

assertArrayEquals(array, result);
assertNotSame(array, result);
assertNull(ArrayUtils.clone((int[]) null));

2. subarray

subarray 用于获取数组切片。

这里的区间语义是 [startIndexInclusive, endIndexExclusive)

代码语言:javascript
复制
final int[] array = new int[]{1, 2, 3, 4};
final int[] result = ArrayUtils.subarray(array, 1, 3);

assertArrayEquals(new int[]{2, 3}, result);

3. arraycopy

arraycopy 是对 System.arraycopy 的流式封装。

它复制数组片段,并返回目标数组,适合希望链式使用复制结果的场景。

代码语言:javascript
复制
final int[] source = new int[]{1, 2, 3};
final int[] destination = new int[]{0, 0, 0};
final int[] result = ArrayUtils.arraycopy(source, 1, destination, 0, 2);

assertSame(destination, result);
assertArrayEquals(new int[]{2, 3, 0}, destination);

九、null 处理

这一类方法用于把 null 数组转换成更安全的默认值。

1. nullToEmpty

nullToEmpty 用于将 null 数组转换为空数组。

如果输入数组非 null,则返回原数组引用。

代码语言:javascript
复制
int[] result = ArrayUtils.nullToEmpty((int[]) null);
assertNotNull(result);
assertEquals(0, result.length);

final int[] array = new int[]{1, 2};
result = ArrayUtils.nullToEmpty(array);
assertSame(array, result);

2. nullTo

nullTo 用于在数组为 null 时返回指定默认数组;否则返回原数组。

它适合为数组参数提供默认值。

代码语言:javascript
复制
final String[] defaultArray = new String[]{"default"};
final String[] array = new String[]{"value"};

assertSame(defaultArray, ArrayUtils.nullTo(null, defaultArray));
assertSame(array, ArrayUtils.nullTo(array, defaultArray));

十、顺序调整

这一类方法用于改变数组中元素的排列顺序。

1. reverse

reverse 用于反转数组元素顺序。

它支持反转整个数组,也支持反转指定范围。

代码语言:javascript
复制
final int[] array = new int[]{1, 2, 3};

ArrayUtils.reverse(array);

assertArrayEquals(new int[]{3, 2, 1}, array);

2. shift

shift 用于循环位移数组元素。

代码语言:javascript
复制
final int[] array = new int[]{1, 2, 3, 4};

ArrayUtils.shift(array, 1);

assertArrayEquals(new int[]{4, 1, 2, 3}, array);

3. swap

swap 用于交换数组中两个位置的元素。

部分重载支持交换两个区间。

代码语言:javascript
复制
final int[] array = new int[]{1, 2, 3};

ArrayUtils.swap(array, 0, 2);

assertArrayEquals(new int[]{3, 2, 1}, array);

4. shuffle

shuffle 用于随机打乱数组顺序。

测试这类方法时,不应断言固定顺序。更合理的方式是:

  • • 验证打乱前后元素集合不变
  • • 使用固定 Random 控制随机源
代码语言:javascript
复制
final int[] array = new int[]{1, 2, 3, 4};

ArrayUtils.shuffle(array, new Random(1));

final int[] sorted = ArrayUtils.clone(array);
Arrays.sort(sorted);
assertArrayEquals(new int[]{1, 2, 3, 4}, sorted);

十一、批量设置

setAll

setAll 用于通过生成函数批量设置数组元素。

常见重载包括:

  • • 使用 IntFunction,根据索引生成值
  • • 使用 Supplier,每次调用生成一个值

它适合需要按规则初始化数组的场景。

代码语言:javascript
复制
final String[] array = new String[3];
final String[] result = ArrayUtils.setAll(array, index -> "v" + index);

assertSame(array, result);
assertArrayEquals(new String[]{"v0", "v1", "v2"}, array);

十二、类型转换

这一类方法用于在基本类型数组、包装类型数组、对象数组和字符串数组之间转换。

1. toObject

toObject 用于将基本类型数组转换为包装类型数组。

代码语言:javascript
复制
final Integer[] result = ArrayUtils.toObject(new int[]{1, 2, 3});

assertArrayEquals(new Integer[]{1, 2, 3}, result);

2. toPrimitive

toPrimitive 用于将包装类型数组转换为基本类型数组。

部分重载支持为 null 元素指定默认值。

代码语言:javascript
复制
final Integer[] array = new Integer[]{1, 2, 3};
final int[] result = ArrayUtils.toPrimitive(array);

assertArrayEquals(new int[]{1, 2, 3}, result);

3. toArray

toArray 用于将可变参数作为数组返回。

它适合简化数组创建表达式。

代码语言:javascript
复制
final String[] result = ArrayUtils.toArray("a", "b", "c");

assertArrayEquals(new String[]{"a", "b", "c"}, result);

4. toStringArray

toStringArray 用于将对象数组转换为字符串数组。

部分重载支持指定 null 元素的替代文本。

代码语言:javascript
复制
final Object[] array = new Object[]{"a", 1, null};
final String[] result = ArrayUtils.toStringArray(array, "NULL");

assertArrayEquals(new String[]{"a", "1", "NULL"}, result);

十三、字符串、哈希值和 Map 表示

这一类方法用于把数组转换为字符串表示、计算哈希值,或把数组形式的数据转换为 Map

1. toString

toString 用于获取数组的字符串表示,支持嵌套数组。

部分重载支持数组为 null 时返回指定字符串。

代码语言:javascript
复制
final int[] array = new int[]{1, 2, 3};
final String result = ArrayUtils.toString(array);

assertNotNull(result);
assertTrue(result.contains("1"));

2. hashCode

hashCode 用于获取数组的哈希码,并能正确处理多维数组。

代码语言:javascript
复制
final int[] array = new int[]{1, 2, 3};
final int code = ArrayUtils.hashCode(array);

assertNotEquals(0, code);

3. toMap

toMap 用于将数组形式的数据转换为 Map

支持的元素形式包括:

  • Map.Entry
  • • 至少包含两个元素的 Object[],其中第一个元素作为 key,第二个元素作为 value
代码语言:javascript
复制
final Object[] array = new Object[]{new Object[]{"a", 1}, new Object[]{"b", 2}};
final Map<Object, Object> result = ArrayUtils.toMap(array);

assertEquals(1, result.get("a"));
assertEquals(2, result.get("b"));

十四、测试覆盖策略

由于 ArrayUtils 的重载非常多,如果对每个重载都写完整测试,测试数量会非常庞大,也容易淹没教程重点。

更适合教程项目的测试策略是:

  1. 1. 每个唯一方法名至少提供一个代表性示例测试。
  2. 2. 对常用方法覆盖基础场景和少量边界场景。
  3. 3. 对基本类型、包装类型、对象类型重载只选择代表类型,不逐个重复。
  4. 4. 对 shuffle 等随机行为避免断言固定顺序,优先验证元素集合不变。
  5. 5. 对 deprecated 方法保留必要示例,用于理解历史 API,但不扩大覆盖范围。

按照该策略,测试既能展示完整 API 面,又不会因为大量重复重载而降低可读性。

十五、总结

ArrayUtils 的核心价值,是把 Java 数组操作中常见的样板代码封装成稳定、统一的工具方法。

如果按使用场景理解,可以把它记成几组能力:

  • • 要新增元素:看 addaddFirstaddAllinsert
  • • 要删除元素:看 removeremoveAllremoveElementremoveElementsremoveAllOccurrences
  • • 要查找元素:看 containscontainsAnyindexOflastIndexOfindexesOf
  • • 要判断数组状态:看 isEmptyisNotEmptyisSameLengthisSameTypeisSorted
  • • 要复制或截取:看 clonesubarrayarraycopy
  • • 要处理 null:看 nullToEmptynullTo
  • • 要调整顺序:看 reverseshiftswapshuffle
  • • 要做类型转换:看 toObjecttoPrimitivetoArraytoStringArray

这样理解之后,ArrayUtils 不再是一长串 API 列表,而是一组围绕数组生命周期展开的工具能力。


本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-06-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DevLlama 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、整体能力概览
  • 二、常量类能力
    • 1. 空数组常量
    • 2. INDEX_NOT_FOUND
  • 三、添加、合并、插入
    • 1. add
    • 2. addFirst
    • 3. addAll
    • 4. insert
  • 四、删除元素
    • 1. remove
    • 2. removeAll
    • 3. removeElement
    • 4. removeElements
    • 5. removeAllOccurrences
    • 6. removeAllOccurences
  • 五、查找和包含判断
    • 1. contains
    • 2. containsAny
    • 3. indexOf
    • 4. lastIndexOf
    • 5. indexesOf
    • 6. startsWith
  • 六、获取元素、长度和类型
    • 1. get
    • 2. getLength
    • 3. getComponentType
    • 4. newInstance
  • 七、判空、比较和排序判断
    • 1. isEmpty
    • 2. isNotEmpty
    • 3. isSameLength
    • 4. isSameType
    • 5. isEquals
    • 6. isSorted
    • 7. isArrayIndexValid
  • 八、克隆、切片和复制
    • 1. clone
    • 2. subarray
    • 3. arraycopy
  • 九、null 处理
    • 1. nullToEmpty
    • 2. nullTo
  • 十、顺序调整
    • 1. reverse
    • 2. shift
    • 3. swap
    • 4. shuffle
  • 十一、批量设置
    • setAll
  • 十二、类型转换
    • 1. toObject
    • 2. toPrimitive
    • 3. toArray
    • 4. toStringArray
  • 十三、字符串、哈希值和 Map 表示
    • 1. toString
    • 2. hashCode
    • 3. toMap
  • 十四、测试覆盖策略
  • 十五、总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档