为什么 Java 8 流接口没有 min() 无参数版本?
java.util.stream.Stream
接口有两个版本的方法 - 它按自然顺序对元素进行排序,然后对元素进行排序。为什么没有将方法引入接口,这将从自然排序的角度返回最小元素?sorted
sorted()
sorted(Comparator)
min()
Stream
java.util.stream.Stream
接口有两个版本的方法 - 它按自然顺序对元素进行排序,然后对元素进行排序。为什么没有将方法引入接口,这将从自然排序的角度返回最小元素?sorted
sorted()
sorted(Comparator)
min()
Stream
应该清楚的是,对于 、 和 ,添加一个不需要比较器的方法会引入一种失去泛型类型安全的方法。原因是Java语言的当前版本不支持将方法限制为特定参数化的实例,即将它们限制为可比较元素的流。min
max
sorted
Stream
所以问题可能是相反的,为什么排序()
允许这种对类型安全的潜在破坏?
我无法深入开发人员的思想,但有一个有趣的观点是,排序已经被特殊对待了很长时间了。随着泛型的引入,可以强制执行没有 a 的排序,只能对具有类似元素的集合或数组进行排序。但是,尤其是在实现泛型集合时,开发人员可能会面临这样一个事实,即无法使用泛型元素类型创建数组。可能还有其他情况,其中开发人员遇到正式上不具有可比性的类型的数组或集合,而包含的元素肯定是可比较的。如前所述,我无法在开发人员的脑海中说出,考虑了哪些场景。Comparator
但
Arrays.sort(Object[])
不强制数组类型为 的子类型。即使确实如此,Comparable
sort(T[] a, Comparator<? super T> c)
指定比较器意味着“自然顺序”,它允许请求任何类型的自然顺序null
Collections.sort(List<T> list)
需要类似的元素类型,但是
Collections.sort(List<T> list, Comparator<? super T> c)
再次指定比较器意味着“自然顺序”,因此仍然有一种简单的方法来破坏类型系统。由于“意味着自然”规则在泛型存在之前就已经指定,因此必须保留它以保持兼容性。null
null
但这不仅仅是向后兼容性。在Java 8中引入的List.sort(Comparator)
也被指定为接受“自然顺序”的参数,所以现在我们有另一个场景,其中实现者可能必须在没有保证可比较元素的编译时类型的情况下对数据进行排序。null
因此,在分类方面,已经有很多机会可以避开类型系统。但是 Stream.sorted(Comparator)
是唯一不接受比较器的排序方法。因此,在不指定的情况下按自然顺序排序只能在没有参数的情况下使用。顺便说一句,使用比较器具有已排序的输入并且没有比较器的请求是Stream实现将检测到排序不是必需的唯一情况,即它不比较比较器并且不检查。null
Comparator.naturalOrder()
sorted()
null
sorted()
Comparator.naturalOrder()
通常,比较器的类型安全性非常弱。例如,Collections.reverseOrder()
返回任意类型的比较器,不要求该类型具有可比性。因此,您可以使用 来请求最小值,而不是 ,而不管流的正式类型如何。或者用于获取任意类型的等效项。同样,Collator
实现了 ,无论出于何种原因,尽管它只能比较 s。min()
max(Collections.reverseOrder())
Collections.reverseOrder(Collections.reverseOrder())
Comparator.naturalOrder()
Comparator<Object>
String
我认为这只会污染API。人们可以说“为什么没有max无参数版本”,“为什么没有CharStream”,它可以在可以提供但决定最好不要的东西方面继续说。
有一个无参数的 min 方法:
someList.stream().min(Comparator.naturalOrder());
也不例外。
因此,最好只是创建一个可重用的方法,而不是用所有可能的东西污染API。