2017-12-16 113 views
6

Giao diện java.util.stream.Stream có hai phiên bản của phương pháp sorted - sorted() sắp xếp các yếu tố theo thứ tự tự nhiên và sorted(Comparator). Tại sao phương thức min() không được đưa vào giao diện Stream, phương thức này sẽ trả lại yếu tố tối thiểu từ quan điểm đặt hàng tự nhiên?Tại sao giao diện Java 8 Stream không có phiên bản không có tham số min()?

+0

Các câu trả lời đã đưa ra là hữu ích, nhưng không hoàn toàn đạt được điểm chính. Vì vậy, có 2 phiên bản của 'sắp xếp' phương pháp -' sắp xếp() 'và' sắp xếp (Comparator) '. Dường như với tôi một chút không nhất quán rằng 'min()' không được giới thiệu cùng với 'min (Comparator)' khi có các phiên bản 'sắp xếp' tương ứng. Nên có một số lý do. – PresentProgrammer

+0

'Stream.sorted()' là một sai lầm. Chỉ nên có 'Stream.sorted (Comparator)'. – ZhekaKozlov

+0

@ZhekaKozlov Tôi cũng nghĩ như vậy, nhưng tôi không thể tìm thấy bất kỳ danh sách gửi thư thảo luận về điều này – Eugene

Trả lời

3

Tôi nghĩ rằng min() chỉ cho phép chữ ký chấp nhận một Trình so sánh vì Luồng có thể thuộc bất kỳ loại nào, thậm chí là loại do bạn tạo. Trong trường hợp như vậy, sẽ không thể dựa vào thứ tự tự nhiên, như lớp bạn đã tạo, không thể có thứ tự tự nhiên cho đến khi bạn chỉ định nó.

Nếu, insteam của lớp Stream bạn sử dụng, IntStream, bạn sẽ thấy rằng một phương thức min() không có đối số được xác định. Điều này làm những gì bạn muốn. Nó là như sau:

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()); 
    } 
+1

Hmmm ... Điểm tốt, nhưng 'sắp xếp()' cũng yêu cầu các phần tử để thực hiện 'Comparable' nhưng nó vẫn được giới thiệu với giao diện. – PresentProgrammer

+0

Tôi nghe bạn. Tôi bắt đầu tò mò về điều này. Một đầu mối khác để tìm ra điều này, có thể, được sắp xếp là một hoạt động trung gian, trong khi min/max thì không. Nhưng tôi không thể thực sự nghĩ rằng làm thế nào điều này có thể giúp – BabaNew

3

Comparator.naturalOrder phục vụ mục đích này. Sự tồn tại của nó (hoặc các triển khai tùy chỉnh của chúng) cho phép các lớp khác trở nên đơn giản hơn vì chúng không phải thực hiện các kiểu mã đặc biệt cho các giá trị null trong các trường Comparator.

Loại của nó cũng sẽ buộc T của luồng thực hiện Có thể so sánh.

+0

Có, 'Comparator.naturalOrder()' giúp trong trường hợp này mà không nghi ngờ gì, nhưng nó vẫn không trả lời câu hỏi (xem bình luận cho câu hỏi chính). – PresentProgrammer

3

Tôi cho rằng điều đó sẽ gây ô nhiễm cho API. người ta có thể nói "tại sao không có phiên bản không có tham số tối đa", "tại sao không có CharStream" và nó có thể bật và bật về những thứ có thể có sẵn nhưng được quyết định là không tốt nhất.

có một parameterless phút phương pháp trên đây:

someList.stream().min(Comparator.naturalOrder()); 

sẽ không có khác nhau.

do đó tốt nhất là chỉ cần tạo một phương thức có thể sử dụng lại thay vì làm ô nhiễm API với tất cả những điều có thể.

+1

Sự ô nhiễm có thể là một điểm tốt, nhưng sau đó tham số-ít 'sắp xếp()' sẽ không được giới thiệu. – PresentProgrammer

3

Nó nên được rõ ràng rằng cho min, max, và sorted, thêm một phương pháp để Stream, mà không đòi hỏi một so sánh, giới thiệu một cách để mất sự an toàn kiểu generic, như phiên bản hiện tại của ngôn ngữ Java không hỗ trợ các phương thức hạn chế đối với các cá thể của một tham số cụ thể, tức là giới hạn chúng thành các luồng của các phần tử có thể so sánh.

Vì vậy, câu hỏi có thể là cách khác vòng, lý do tại sao có khả năng phá vỡ an toàn loại này được phép với sorted()?

Tôi không thể nhìn vào tâm trí của nhà phát triển, nhưng một điểm thú vị là, việc phân loại đó đã được xử lý đặc biệt trong một thời gian dài. Với sự ra đời của Generics, có khả năng thực thi việc phân loại mà không cần Comparator chỉ có thể được thực hiện cho các bộ sưu tập hoặc các mảng với các phần tử tương đương. Tuy nhiên, đặc biệt là khi triển khai các bộ sưu tập chung, các nhà phát triển có thể phải đối mặt với thực tế là các mảng không thể được tạo bằng loại phần tử chung. Có thể có các trường hợp khác, trong đó nhà phát triển gặp một mảng hoặc tập hợp một loại chính thức không thể so sánh trong khi các phần tử được chứa có thể so sánh được chắc chắn. Như đã nói, tôi không thể nhìn vào tâm trí của nhà phát triển để nói, những tình huống nào được xem xét.

Nhưng

Nhưng nó không chỉ là về khả năng tương thích ngược. List.sort(Comparator), được giới thiệu trong Java 8, cũng được chỉ định là chấp nhận null làm đối số cho “thứ tự tự nhiên”, vì vậy bây giờ chúng tôi có một tình huống khác, nơi người triển khai có thể phải sắp xếp dữ liệu mà không có loại biên dịch đảm bảo các yếu tố có thể so sánh.

Vì vậy, khi nói đến sắp xếp, đã có rất nhiều cơ hội để né tránh hệ thống kiểu. Nhưng Stream.sorted(Comparator) là phương pháp sắp xếp duy nhất không chấp nhận bộ so sánh null. Vì vậy, sắp xếp theo thứ tự tự nhiên mà không chỉ định Comparator.naturalOrder() chỉ có thể sử dụng sorted() không có đối số. Nhân tiện, có một đầu vào đã được sắp xếp với bộ so sánh null và yêu cầu sorted() mà không so sánh là tình huống duy nhất mà việc triển khai Luồng sẽ phát hiện việc phân loại đó là không cần thiết, tức là nó không so sánh các bộ so sánh và không kiểm tra Comparator.naturalOrder().

Nói chung, loại an toàn của bộ so sánh là yếu đáng kinh ngạc. Ví dụ. Collections.reverseOrder() trả về một bộ so sánh loại tùy ý, không yêu cầu loại so sánh được. Vì vậy, thay vì min(), bạn có thể sử dụng max(Collections.reverseOrder()) để yêu cầu mức tối thiểu, bất kể loại chính thức của luồng. Hoặc sử dụng Collections.reverseOrder(Collections.reverseOrder()) để nhận số tiền tương đương Comparator.naturalOrder() cho loại tùy ý. Tương tự, Collator thực hiện Comparator<Object>, vì bất kỳ lý do gì, mặc dù nó chỉ có thể so sánh String s.

+0

ý của bạn là gì khi 'giới hạn chúng thành luồng các phần tử có thể so sánh'? Một cách để nói rằng trừ khi có một loại 'T mở rộng Comparable ...', bạn không thể có khả năng hiển thị (truy cập) một phương thức 'max', hãy nói? – Eugene

+1

@Eugene: vâng, một cách giả định để nói "phương pháp này chỉ có thể được gọi, nếu mục tiêu có thể gán cho' Stream > '". Đã có cú pháp cho phép thêm chú thích vào loại của 'this' này, do đó, về mặt cú pháp, thay đổi sẽ không quá lớn. Nhưng về mặt ngữ nghĩa, nó sẽ là một bước tiến lớn. – Holger

Các vấn đề liên quan