Arrays.stream().distinct()对引用类型数组天然有效,对基本类型需先转包装类型流;自定义对象须重写equals/hashCode才能按值去重;支持链式去重+映射+收集。
用 arrays.stream().distinct() 对原始数组去重,关键在于“原始数组”类型——它只对引用类型数组(如 string[]、integer[])天然有效;对基本类型数组(如 int[]、double[])需先转为包装类型流,否则会把整个数组当一个对象处理,无法真正去重。
对引用类型数组:直接 distinct 即可
例如 String[] 或 Integer[],元素本身有合理的 equals/hashCode,distinct() 能按值去重:
String[] arr = {"a", "b", "a", "c"};
String[] unique = Arrays.stream(arr)
.distinct()
.toArray(String[]::new); // ["a", "b", "c"]
对基本类型数组:必须先升维或映射
int[] 传入 Arrays.stream() 得到的是 IntStream,而 IntStream.distinct() 是有效的——但它返回的仍是 IntStream,不能直接转成 int[] 以外的类型。若目标是转成 Integer[] 或 List<Integer>,需用 boxed():
-
转回 int[]:直接用
IntStream.distinct().toArray() -
转成 Integer[]:加
.boxed().toArray(Integer[]::new) -
转成 List<Integer>:加
.boxed().collect(Collectors.toList())
int[] nums = {1, 2, 2, 3, 1};
int[] uniqueInts = Arrays.stream(nums).distinct().toArray(); // [1, 2, 3]
Integer[] uniqueBoxed = Arrays.stream(nums)
.distinct()
.boxed()
.toArray(Integer[]::new); // [1, 2, 3]
注意 equals 语义:自定义对象要重写 equals & hashCode
若数组元素是自定义类(如 User[]),distinct() 是否生效,完全取决于该类是否正确重写了 equals() 和 hashCode()。否则默认按引用比较,相同内容的不同实例不会被去重。
例如未重写时:
User u1 = new User("Alice", 25);
User u2 = new User("Alice", 25); // 内容相同但不同对象
User[] users = {u1, u2};
// Arrays.stream(users).distinct().count() → 2(不是 1!)
极简转换链:去重 + 映射 + 收集一步到位
常见需求如“去重后转大写再收集为 List”:
String[] arr = {"hello", "world", "hello"};
List<String> result = Arrays.stream(arr)
.distinct()
.map(String::toUpperCase)
.collect(Collectors.toList()); // ["HELLO", "WORLD"]
这种链式写法清晰、不可变、无副作用,是函数式去重转换的推荐范式。


















