跳到主要内容

ArrayUtil 数组工具类

📦 包路径top.csaf.lang.ArrayUtil

🔗 所属模块zutil-core

ArrayUtil 是在 org.apache.commons.lang3.ArrayUtils 基础上的扩展。 这意味着除了可以使用 Apache Commons 提供的所有标准数组操作(如 isEmpty, add, contains, reverse 等)外,还额外提供了一系列增强功能,重点解决了字符集转换数组去重位移填充等场景痛点。

✨ 核心特性

  • 完全兼容:继承自 Commons Lang3,无缝兼容现有代码。
  • 全类型支持:所有方法均重载支持 Java 的 8 种基本数据类型 (int, long, byte, char, double, float, short, boolean) 及其包装类。
  • 编码转换:提供 char[]byte[]String 之间基于 Charset 的便捷互转。
  • 高级去重:提供保留首位、保留末位、倒序去重、Hash 去重等多种策略。
  • 智能填充:增强版 fill,支持自动扩容(超出长度自动创建新数组,未超出则原地修改)。
  • 特殊位移:支持数组元素的向前位移(删除区间并左移)与定长删除。

🚀 常用方法概览

1. 编码与类型转换 (Conversion)

简化了字符数组、字节数组与字符串之间的转换,支持指定字符集(默认 UTF-8)。

方法名描述示例
toBytes(char[], [Charset])字符数组转字节数组['a','b'] -> [97, 98]
toChars(byte[], [Charset])字节数组转字符数组[97, 98] -> ['a','b']
toString(byte[], [Charset])字节数组转字符串[97, 98] -> "ab"

示例代码:

char[] chars = {'H', 'e', 'l', 'l', 'o'};

// 转为 UTF-8 字节数组
byte[] bytes = ArrayUtil.toBytes(chars);

// 指定字符集转换 (支持 String 或 Charset 对象)
byte[] gbkBytes = ArrayUtil.toBytes(chars, "GBK");

// 还原
String str = ArrayUtil.toString(bytes); // -> "Hello"

2. 数组去重 (Deduplication)

提供多种去重算法,以满足对结果顺序的不同需求。所有去重方法均返回新数组

方法名描述结果示例 ([A, B, A])
deduplicate保留首位。保留第一个出现的元素,后续重复的删除。[A, B]
deduplicatePreceding保留末位。保留最后一次出现的元素。[B, A]
deduplicateReverse倒序去重。去重后按自然顺序倒序排列 (TreeSet)。[B, A] (若B>A)
deduplicateHashSortHash去重。基于 HashMap 去重,顺序取决于 Hash 分布。(无序)

示例代码:

Integer[] nums = {1, 2, 3, 1, 2};

// 1. 普通去重 (保留前)
Integer[] res1 = ArrayUtil.deduplicate(nums);
// -> [1, 2, 3]

// 2. 保留后去重 (特定场景下需要保留最新数据的引用)
Integer[] res2 = ArrayUtil.deduplicatePreceding(nums);
// -> [3, 1, 2]

// 3. 倒序去重 (利用 TreeSet)
Integer[] res3 = ArrayUtil.deduplicateReverse(nums);
// -> [3, 2, 1]

3. 数组操作与填充 (Manipulation)

3.1 智能填充 (Auto-Expanding Fill)

标准的 Arrays.fill 如果索引越界会抛出异常,而 ArrayUtil.fill 支持自动扩容。

方法名描述
fill(array, fromIndex, toIndex, value)填充数组。注意返回值:若 toIndex 超出原长度,返回新数组;若未超出,则修改原数组并返回。
int[] arr = {1, 2};

// 场景1:扩容填充 (范围 2~4 超出原长度 2)
// 返回新数组 [1, 2, 9, 9]
int[] newArr = ArrayUtil.fill(arr, 2, 4, 9);

// 场景2:原地填充 (范围 0~1 在原长度内)
// 修改原数组为 [9, 2] 并返回
ArrayUtil.fill(arr, 0, 1, 9);

3.2 定长删除 (Remove & Keep Length)

用于保持数组长度不变的场景:删除指定位置元素,后续元素前移,并将指定的值填充到数组最后一位。此方法始终返回新数组

方法名描述
remove(array, index, lastElementValue)删除指定索引元素,左移后续元素,末尾填充 lastElementValue
String[] arr = {"A", "B", "C", "D"};

// 删除索引 1 ("B"),后续元素 ("C","D") 前移,末尾填充 "End"
String[] res = ArrayUtil.remove(arr, 1, "End");
// -> ["A", "C", "D", "End"]

3.3 区间前移 (Move Forward)

将数组中指定区间的数据删除,并将后面的数据向前移动。数组长度保持不变,末尾多出的位置将被重置为默认值(0, false, null 等)。

方法名描述
moveForward(array, startIndex, length)删除 startIndex 起始的 length 个元素,后续前移。
int[] arr = {10, 20, 30, 40, 50};

// 从下标 1 开始,"吃掉" 2 个长度 (即删除 20, 30)
// 将 40, 50 前移,末尾补 0
int[] res = ArrayUtil.moveForward(arr, 1, 2);
// -> [10, 40, 50, 0, 0]

3.4 移除指定元素 (Remove Elements)

根据参数列表移除数组中的元素。注意:此方法移除的是“参数中指定的次数”,而非移除所有重复项。

方法名描述
removeAllElements(array, values...)删除数组中与 values 匹配的元素(每个参数移除一个匹配项)。
int[] arr = {1, 0, 2, 0, 3, 5};

// 删除一个 0 和一个 5
int[] res = ArrayUtil.removeAllElements(arr, 0, 5);
// -> [1, 2, 0, 3] (注意:数组中第二个 0 被保留了)

4. 查找与统计 (Search & Stat)

方法名描述
indexOf(char[] array, String str, [int startIndex])在字符数组中查找字符串出现的位置。针对 2 字符的查找进行了性能优化。
allLength(String... strs)计算多个字符串的长度总和。
char[] buffer = {'H', 'e', 'l', 'l', 'o'};

// 在字符数组中查找子串 "ll"
int index = ArrayUtil.indexOf(buffer, "ll");
// -> 2

// 统计长度
int len = ArrayUtil.allLength("Hello", "World");
// -> 10