为什么Java 8 Stream接口没有min()无参数版本? [英] Why Java 8 Stream interface does not have min() no-parameter version?

查看:211
本文介绍了为什么Java 8 Stream接口没有min()无参数版本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

java.util.stream.Stream 接口有两个版本的已排序方法 - sorted()按自然顺序对元素进行排序,排序(比较器)。为什么 min()方法没有引入 Stream 接口,这将从自然顺序的角度返回最小元素?

java.util.stream.Stream interface has two versions of sorted method – sorted() which sorts elements in natural order and sorted(Comparator). Why min() method was not introduced to Stream interface, which would return minimal element from natural-ordering point of view?

推荐答案

应该很清楚,对于 min max 已排序,向 Stream 添加一个不需要的方法比较器引入了一种失去通用类型安全性的方法。原因是当前版本的Java语言不支持将方法限制为特定参数化的实例,即将它们限制为可比较元素的流。

It should be clear that for min, max, and sorted, adding a method to Stream that does not require a comparator introduces a way to lose the generic type safety. The reason is that the current version of the Java language does not support restricting methods to instances of a specific parameterization, i.e. limit them to streams of comparable elements.

所以问题可能是反过来,为什么 sorted()

So the question could be the other way round, why has this potential break of the type safety been allowed with sorted()?

我无法深入了解开发人员的想法,但有一点有趣的是,排序已经被特别处理了很长时间。随着Generics的引入,可以强制执行排序,而不需要 Comparator 只能尝试具有可比元素的集合或数组。但是,特别是在实现泛型集合时,开发人员可能会面临无法使用泛型元素类型创建数组的事实。可能存在其他情况,其中开发人员遇到正式不可比较类型的数组或集合,而包含的元素肯定是可比较的。如上所述,我无法调查开发人员的想法,考虑哪些方案。

I can’t look into the developers mind, but one interesting point is that sorting has been treated specially for a long time now. With the introduction of Generics, it became possible to enforce that sorting without a Comparator can only be attempted for collections or arrays with comparable elements. However, especially when implementing generic collections, developers might face the fact that arrays can’t be created with a generic element type. There might be other scenarios, where a developer encounters an array or collection of a formally non-comparable type while the contained elements are comparable for sure. As said, I can’t look into the developers mind to say, which scenarios were considered.

但是

  • Arrays.sort(Object[]) does not enforce the array type to be a subtype of Comparable. Even if it did,
  • sort(T[] a, Comparator<? super T> c) specifies that a null comparator implies "natural order", which allows requesting natural order for any type
  • Collections.sort(List<T> list) requires a comparable element type, but
  • Collections.sort(List<T> list, Comparator<? super T> c) again specifies that a null comparator implies "natural order", so there’s still an easy way to undermine the type system. Since the "null means natural" rule was already specified before Generics existed, it had to be kept for compatibility.

但这不仅仅是向后兼容性。 在Java 8中引入的List.sort(Comparator) 也被指定为接受 null 作为自然顺序的参数,所以现在我们有另一个场景,实现者可能必须在没有编译时类型的情况下对数据进行排序,以保证可比较的元素。

But it’s not just all about backwards compatibility. List.sort(Comparator), introduced in Java 8, is also specified as accepting null as argument for "natural order", so now we have another scenario, where an implementer might have to sort data without a compile-time type that guarantees comparable elements.

所以当涉及到排序时,有很多机会躲避类型系统。但 Stream.sorted(Comparator) 是唯一不接受 null 比较器的排序方法。因此,只能使用 Comparator.naturalOrder()进行自然顺序排序,只能使用不带参数的 sorted()。顺便说一下,在没有比较器的情况下,使用 null 比较器进行已排序的输入并请求 sorted()是唯一的情况Stream实现将检测到排序是不必要的,即它不比较比较器并且不检查 Comparator.naturalOrder()

So when it comes to sorting, there are already lots of opportunities to dodge the type system. But Stream.sorted(Comparator) is the only sort method not accepting a null comparator. So sorting by natural order without specifying Comparator.naturalOrder() is only possible using sorted() without arguments. By the way, having an already sorted input with a null comparator and requesting sorted() without comparator is the only situation where the Stream implementation will detect that sorting isn’t necessary, i.e. it doesn’t compare comparators and doesn’t check for Comparator.naturalOrder().

一般来说,比较器的类型安全性是惊人的弱点。例如。 Collections.reverseOrder () 返回任意类型的比较器,不要求类型可比。因此,您可以使用 max(Collections.reverseOrder())代替 min()来请求最小值,无论如何流的正式类型。或者使用 Collections.reverseOrder(Collections.reverseOrder())获取相当于 Comparator.naturalOrder()的内容任意型。同样, Collat​​or 实现 Comparator< Object> ,无论出于何种原因,尽管它只能比较 String s 。

Generally, the type safety of comparators is astonishing weak. E.g. Collections.reverseOrder() returns a comparator of arbitrary type, not demanding the type to be comparable. So instead of min(), you could use max(Collections.reverseOrder()) to request the minimum, regardless of the stream’s formal type. Or use Collections.reverseOrder(Collections.reverseOrder()) to get the equivalent of Comparator.naturalOrder() for an arbitrary type. Likewise, Collator implements Comparator<Object>, for whatever reason, despite it can only compare Strings.

这篇关于为什么Java 8 Stream接口没有min()无参数版本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆