2017-06-11 36 views
13

Trong khi làm hoạt động dòng, trong quá trình hoạt động trung gian/pipleline các dòng sẽ được tạo ra với những đặc điểm khác nhau (ví dụ như sắp xếp/VỪA/DISTINCT/RA LỆNH) - Mastering Lambdas (Ch 6)Cách tìm đúng các đặc tính luồng trong Java-8?

Stream.of(8,3,5,6,7,4)//ORDERED, SIZED 
.filer(i->i%2==0) // ORDERED 
.sorted() // ORDERED, SORTED 
.distinct() // DISTINCT, ORDERED, SORTED 
.map(i->i+1) // ORDERED 
.unordered(); //none 

Làm thế nào để chúng ta tìm hiểu các đặc điểm khác nhau của luồng như được đề cập trong đoạn mã trên?

Trả lời

8

Tôi muốn một chút mở rộng những gì assylias nói (mà là hoàn toàn chính xác).

Đầu tiên, các đặc điểm này được triển khai dưới dạng đơn giản int, đây là biểu diễn nhị phân. Đầu tiên là tất cả các số 0, nhưng khi bạn thêm một đặc tính nhất định, bit đó được đặt thành one qua thao tác OR, bị xóa qua thao tác AND.

Bạn có thể nhìn thấy nơi một tài sản nhất định Spliterator đặt one nó chỉ đơn giản bằng cách làm này ví dụ:

System.out.println(Integer.toBinaryString(Spliterator.SIZED)); // 1000000 

Nó thiết lập các bit 7-thứ vào một từ cánh phải. Vì vậy, khi bạn kiểm tra:

Spliterator<Integer> spliterator = Stream.of(8, 3, 5, 6, 7, 4).spliterator(); 
System.out.println((spliterator.characteristics() & Spliterator.SIZED) == Spliterator.SIZED); 

Bạn đang thực sự kiểm tra nếu đặc biệt bit này được thiết lập.

Second

Có đặc điểm dòng được thiết lập như là kết quả của sự sáng tạo của bạn đầu tiên dòng (và không phải là hai). Hoặc là cuốn sách là một chút lỗi thời hoặc bạn đã không cho chúng ta thấy toàn bộ ví dụ:

Spliterator<Integer> spliterator = Stream.of(8, 3, 5, 6, 7, 4).spliterator(); 

System.out.println(Integer.bitCount(spliterator.characteristics())); // 4 
System.out.println(Integer.toBinaryString(spliterator.characteristics()));// 100010001010000 

Những bộ bit (tức là tương đương với one) tương ứng với SIZED, ORDERED, IMMUTABLE, SUBSIZED.

Các thiết bị khác mà bạn đã hiển thị rõ ràng hơi bị tắt - bạn có thể tự mình kiểm tra.

Thứ ba

Những đặc điểm này là vô cùng quan trọng trong việc xử lý dòng.Một vài ví dụ:

long howMany = Stream.of(1, 2, 3).map(x -> { 
     System.out.println("mapping"); 
     return x * 2; 
    }).count(); 
    System.out.println(howMany); // 3 

Trong java-9, bạn sẽ không nhìn thấy mapping in, bởi vì bạn đã không thay đổi luồng (bạn chưa xóa các đặc trưng SIZED); do đó không cần phải đánh giá bản đồ cả.

Stream<Integer> unlimited = Stream.iterate(0, x -> x + 1); 
System.out.println(unlimited.spliterator().hasCharacteristics(Spliterator.SIZED)); 
Stream<Integer> limited = unlimited.limit(3);   
System.out.println(limited.spliterator().hasCharacteristics(Spliterator.SIZED)); 

Bạn sẽ nghĩ rằng sản lượng nên được false true - chúng tôi có thêm một limit sau khi tất cả, nhưng không có; kết quả là false false: không có tối ưu hóa như vậy được thực hiện, ngay cả khi không có nhiều ngăn chặn nó.

+0

Không, tôi đã đưa ra toàn bộ đoạn trích. Có thể tôi đã có phiên bản cũ của cuốn sách. –

+0

Ví dụ thứ ba (đoạn thứ hai), không jdk9 không quan tâm đến điều đó? –

9

Tại mỗi giai đoạn bạn có thể gọi:

int c = stream.spliterator().characteristics(); 

Và sau đó kiểm tra kết quả so với các hằng số được định nghĩa trong lớp Spliterator. Ví dụ để xem nếu dòng được ra lệnh:

boolean isOrdered = (c & Spliterator.ORDERED) == Spliterator.ORDERED; 

Hoặc bạn có thể sử dụng:

boolean isOrdered = stream.spliterator().hasCharacteristics(Spliterator.ORDERED); 
+0

bạn không thể làm điều đó * ở mỗi giai đoạn *, luồng sẽ bị tiêu thụ ... – Eugene

+3

@Eugene: bạn có thể tạo lại luồng từ trình tách biệt, [xem tại đây] (https://stackoverflow.com/a/28475289/2711488), tôi cho rằng, đây là những gì OP là sau ... – Holger

+2

@ Holger ah! điều đó sẽ có ý nghĩa để trả lại luồng từ trình tách biệt đó ... thx. chân thành congrats trên 100k. – Eugene

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