商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 编程开发 > 怎么通过 Arrays.stream().distinct() 极简实现对原始数组元素的去重与转换

怎么通过 Arrays.stream().distinct() 极简实现对原始数组元素的去重与转换

  发布于2026-07-09 阅读(0)

扫一扫,手机访问

一句话总结:Arrays.stream().distinct() 对引用类型数组天生有效,对基本类型需要先转包装流;自定义对象必须正确重写 equalshashCode 才能按值去重;并且可以一条链式调用搞定去重、映射和收集。

很多人在处理数组去重时,第一个想到的就是 Arrays.stream().distinct()。但关键要看清楚:你传进去的“原始数组”是什么类型。对于 String[]Integer[] 这类引用类型数组,它能直接识别出重复元素,一个 distinct() 就搞定了。可一旦换成 int[]double[] 这样的基本类型数组,情况就变了——如果不做特殊处理,Stream 会傻乎乎地把整个数组当成一个对象来处理,根本不会去遍历里面的元素,更别说去重了。

怎么通过 Arrays.stream().distinct() 极简实现对原始数组元素的去重与转换

对引用类型数组:直接 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[],直接 .distinct().toArray() 就行。但更多场景下我们需要的是 Integer[]List,这时就必须调用 boxed() 把基本类型装箱:

  • 转回 int[]IntStream.distinct().toArray()
  • 转成 Integer[]IntStream.distinct().boxed().toArray(Integer[]::new)
  • 转成 ListIntStream.distinct().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]

注意不要在 IntStream 上直接调用 .toArray(Integer[]::new),那会编译报错——必须先装箱。

注意 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!)

这一点经常被忽略,但只要记住一条原则:任何需要按值比较的场景,都别忘记给自定义类实现 equals/hashCode,否则 distinct() 等于白用。

极简转换链:去重 + 映射 + 收集一步到位

实际开发中我们经常需要“先去重、再转换、最后收集”的一连串操作。这时候链式写法就体现出优势了:

String[] arr = {"hello", "world", "hello"};
List result = Arrays.stream(arr)
    .distinct()
    .map(String::toUpperCase)
    .collect(Collectors.toList()); // ["HELLO", "WORLD"]

这种写法清晰、不可变、没有副作用,是函数式去重转换的推荐范式。只要记住上述几个注意点(引用类型直接去重、基本类型先装箱、自定义对象重写 equals),你就能用 Arrays.stream().distinct() 把数组去重这件事做得简洁又优雅。

本文转载于:https://www.php.cn/faq/2407899.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注