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) |
deduplicateHashSort | Hash去重。基于 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