Pre*_*mer 11 java-8 java-stream
java.util.stream.Streaminterface有两个版本的sorted方法 - sorted()按自然顺序对元素进行排序sorted(Comparator).为什么min()没有将方法引入Stream接口,这会从自然顺序的角度返回最小元素?
Hol*_*ger 11
应该清楚的是,for min,max和sorted,添加一个方法Stream,不需要比较器引入一种方法来失去泛型类型的安全性.原因是当前版本的Java语言不支持将方法限制为特定参数化的实例,即将它们限制为可比较元素的流.
所以问题可能是反过来,为什么允许这种类型安全的潜在破坏sorted()?
我无法深入了解开发人员的想法,但有一点有趣的是,排序已经被特别处理了很长时间.随着泛型的引入,有可能强制执行排序,而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比较器意味着"自然顺序",因此仍然有一种简单的方法来破坏类型系统.由于在Generics存在之前已经指定了" null自然意味着"规则,因此必须保持其兼容性.但它不仅仅是向后兼容性.List.sort(Comparator)在Java 8中引入,也被指定为接受null"自然顺序"的参数,所以现在我们有另一个场景,其中实现者可能必须在没有保证可比元素的编译时类型的情况下对数据进行排序.
因此,在排序时,已经有很多机会躲避类型系统.但是Stream.sorted(Comparator)唯一不接受null比较器的排序方法.因此,Comparator.naturalOrder()只有在没有指定的情况下才能使用自然顺序进行排序sorted().顺便说一句,使用null比较器进行已排序的输入并且sorted()不使用比较器进行请求是Stream实现将检测到不需要排序的唯一情况,即它不比较比较器而不检查Comparator.naturalOrder().
通常,比较器的类型安全性是惊人的弱.例如,Collections.reverseOrder()返回任意类型的比较器,不要求类型可比较.因此,无论流的正式类型如何min(),您都可以使用max(Collections.reverseOrder())请求最小值.或者Collections.reverseOrder(Collections.reverseOrder())用来获得Comparator.naturalOrder()任意类型的等价物.同样,Collator工具Comparator<Object>,无论出于何种原因,尽管它只能比较Strings.
我认为这只会污染API.人们可以说"为什么没有最大的无参数版本","为什么没有CharStream",它可以在可以提供但最好不要的事情方面继续.
对此有一个无参数min方法:
someList.stream().min(Comparator.naturalOrder());
Run Code Online (Sandbox Code Playgroud)
没有什么不同.
因此,最好只创建一个可重用的方法,而不是用所有可能的东西来污染API.
我认为 min() 只允许接受比较器的签名,因为 Stream 可以是任何类型,甚至是您创建的类型。在这种情况下,不可能依赖自然顺序,因为您创建的类在指定之前不能具有自然顺序。
如果在您使用的 Stream 类 IntStream 中,您将看到定义了一个不带参数的 min() 方法。这就是你想要的。其内容如下:
public static void main (String... args){
IntStream s=IntStream.of(1,2,3,4,5,6,7,8,9,10);
System.out.println(s.min().getAsInt());
}
Run Code Online (Sandbox Code Playgroud)