2017-06-05 44 views
5

Tôi đã có một java.util.stream.Stream chứa các cặp giá trị quan trọng như:Java 8: Thực hiện giảm hoạt động trên suối

<1,3> <1,5> <3,1> <4,2> <4,7> <4,8> 

Bây giờ tôi muốn hợp nhất tất cả các mục, trong đó đã có cùng khóa:

<1,[3,5]> <3,[1]> <4,[2,7,8]> 

Dữ liệu đã được sắp xếp, vì vậy chỉ có các tập dữ liệu liên tiếp phải được hợp nhất.

Bây giờ, tôi đang tìm cách chuyển đổi nội dung của luồng như trên, mà không cần tải tất cả bộ dữ liệu vào bộ nhớ.

Tôi muốn có được một java.util.stream.Stream như là kết quả với một loại đối tượng khác nhau có chứa một danh sách các giá trị thay vì một giá trị duy nhất.

Cách tiếp cận duy nhất của tôi là một trình vòng lặp tùy chỉnh, thực hiện quá trình hợp nhất, nhưng có vẻ như khá xấu để chuyển đổi sang trình lặp và quay lại luồng.

Cách tiếp cận tốt nhất cho nó là gì?

+6

Bạn đã tìm thấy lựa chọn tốt nhất có thể. Luồng không thực sự có ý nghĩa đối với loại hoạt động bạn muốn. –

+0

Tôi nghĩ hoạt động '.groupBy()' có thể hoạt động tùy thuộc vào chính xác những gì có trong luồng. @LouisWasserman có thể đã hiểu yêu cầu của bạn tốt hơn, tuy nhiên. – KevinO

+0

@KevinO, OP đặc biệt nói rằng họ không muốn một Luồng như một kết quả, và để tránh tải dữ liệu vào bộ nhớ. 'groupingBy' sẽ không cho phép bạn làm điều đó. –

Trả lời

4

Đây là giải pháp của SteamEx.

int[][] datasets = { { 1, 3 }, { 1, 5 }, { 3, 1 }, { 4, 2 }, { 4, 7 }, { 4, 8 } }; 

StreamEx.of(datasets) // 
     .collapse((a, b) -> a[0] == b[0], groupingBy(a -> a[0], mapping(a -> a[1], toList()))) // 
     .forEach(System.out::println); 

bạn có thể thay thế int[] bằng đối tượng dataset của mình. Chúng tôi có thể thêm peek để xác minh xem đó là tải/tính toán lười biếng:

StreamEx.of(datasets) // 
     .peek(System.out::println) // 
     .collapse((a, b) -> a[0] == b[0], groupingBy(a -> a[0], mapping(a -> a[1], toList()))) // 
     .limit(1) // 
     .forEach(System.out::println); 
Các vấn đề liên quan