2014-12-19 22 views
5

Bộ sưu tập của Scala cung cấp một phương pháp được gọi là collect hợp nhất filtermap thành một phương pháp duy nhất. Nó đặc biệt hữu ích khi lọc một bộ sưu tập Object để tạo ra một tập con của bộ sưu tập đó chỉ chứa một kiểu cụ thể.Có phương pháp Luồng Java tương đương với bộ sưu tập của Scala "thu thập" không?

Có bất kỳ điều nào như vậy với Luồng Java 8 không?

+1

Tôi cho rằng bạn đã biết rằng bạn có thể làm điều đúng bằng cách chuỗi các lệnh 'map',' filter' và 'collect'. Vì vậy, mục đích của yêu cầu của bạn để làm điều đó trong một cuộc gọi phương thức là gì? Bởi vì điều đó "cảm thấy" như là hiệu quả hơn? – Holger

+0

@Holger Nó liên kết tiền tố với hàm ánh xạ, giúp làm rõ một _is_ một điều kiện trước cho điều kiện khác, cũng như làm cho nó không thể phá vỡ mã bằng cách thay đổi thứ tự của các cuộc gọi phương thức. –

+3

Thực ra, điều ngược lại. Không ai có thể nói từ chữ ký của một phương thức có chứa hàm ánh xạ và một vị từ được áp dụng trước tiên. Ngược lại, với API 'Stream', mọi người hiểu được sự khác biệt giữa' map (…) .filter (…) .collect (…) 'và' .filter (…) .map (…) .collect (…) '. Và thậm chí có thể suy ra ý nghĩa của các kết hợp khác như 'map (…) .filter (…) .map (…) .collect (…)'… – Holger

Trả lời

7

Có một sự kết hợp của filtermap trong một bước mà không phải là hữu ích trong Java cho hệ thống kiểu của nó. Ví dụ. không có loại PartialFunction như vậy.

Điều gần nhất là flatMap:

List<Object> list=Arrays.asList(0, "foo", 0L, 42.0, true, "false"); 
List<String> sList = list.stream() 
    .flatMap(o-> o instanceof String? Stream.of((String)o): Stream.empty()) 
    .collect(Collectors.toList()); 
System.out.println(sList); 

nhưng biểu cảm của

.flatMap(o-> o instanceof String? Stream.of((String)o): Stream.empty()) 

mà không phải là lớn hơn so với

.filter(o -> o instanceof String).map(o -> (String)o) 

Tất nhiên, bạn có thể tạo ra một phương pháp helper đóng gói các bước này trong một thao tác đơn lẻ, không thể giải quyết được:

static <T> Stream<T> onlyType(Stream<?> s, Class<T> type) { 
    return s.filter(type::isInstance).map(type::cast); 
} 

sau đó bạn có thể sử dụng nó như

List<String> sList=onlyType(list.stream(), String.class).collect(Collectors.toList()); 
0

Tôi cố gắng để cung cấp câu trả lời của câu hỏi của bạn như tôi đọc ở đâu đó -

<R,A> R collect(Collector<? super T,A,R> collector) 

R - loại kết quả A - loại tích lũy trung gian của các nhà sưu tập Collector - Collector mô tả giảm Lợi nhuận - kết quả của việc giảm

Thực hiện thao tác giảm đột biến trên các phần tử của luồng này bằng Bộ sưu tập. Bộ sưu tập đóng gói các chức năng được sử dụng làm đối số để thu thập (Nhà cung cấp, BiConsumer, BiConsumer), cho phép tái sử dụng các chiến lược thu thập và thành phần của các hoạt động thu thập như phân nhóm nhiều cấp hoặc phân vùng. Nếu luồng song song và Bộ thu là đồng thời và luồng không có thứ tự hoặc bộ thu không theo thứ tự thì việc giảm đồng thời sẽ được thực hiện (xem Bộ thu để biết chi tiết về giảm đồng thời.)

Đây là thiết bị đầu cuối hoạt động.

Khi được thực thi song song, nhiều kết quả trung gian có thể được khởi tạo, được điền và hợp nhất để duy trì sự cô lập cấu trúc dữ liệu có thể thay đổi. Do đó, ngay cả khi được thực thi song song với các cấu trúc dữ liệu không an toàn (chẳng hạn như ArrayList), không cần đồng bộ hóa bổ sung để giảm song song.

Sau đây sẽ tích lũy chuỗi thành một ArrayList:

List<String> asList = stringStream.collect(Collectors.toList()); 

Sau đây sẽ phân loại đối tượng Person của nhà nước và thành phố, tầng hai thu gom với nhau:

Map<String, Map<String, List<Person>>> peopleByStateAndCity 
    = personStream.collect(Collectors.groupingBy(Person::getState, 
                Collectors.groupingBy(Person::getCity))); 
+0

Tôi không nói về phương thức 'Thu thập' của' Phương thức 'của Java 8. Tôi đang nói về phương thức 'collect' của Scala và yêu cầu tương đương trong Java 8. –

0

Theo như tôi có thể nói từ giao diện Stream và một số thư viện hỗ trợ, không có hoạt động đơn lẻ thực hiện cả hai thao tác này và tạo ra kết quả Stream (dựa trên readin ngắn của tôi g của phương pháp Scala collect).

Bạn sẽ cần phải áp dụng cả hai hàm vào Stream để có được kết quả mong muốn Stream mà sau đó có thể được thu thập hoặc bất kỳ chức năng nào khác mà bạn muốn áp dụng cho nó.

collection.stream() 
    .filter(predicateFunction) 
    .map(mappingFunction) 
    .collect(Collectors.toList()) 
+1

Đó là * một thao tác đơn lẻ, nhưng thao tác đó được chuẩn bị bằng cách sử dụng các lời gọi phương thức xích mà chỉ nâng cao tính linh hoạt của API. – Holger

0

Khi tôi hiểu tài liệu Scala, collect bộ lọc dựa trên chức năng có hiện diện hay không và áp dụng chức năng cho từng đối tượng đủ điều kiện. Một lớp Java có một định nghĩa cố định, vì vậy một bài kiểm tra như vậy sẽ không có ý nghĩa nhiều. Các analog gần nhất sẽ được thử nghiệm cho một giao diện và cách gọi phương pháp của nó (chức năng) trong nhiều bước:

stream.filter(e -> e instanceof SomeInterface).map(SomeInterface.class::cast).map(AnotherClass::convertSomeInterfaceToSomethingElse) 
0

Hãy thử như thế này

tList.stream().map[E](func).collect(Collectors.toList[E]) 

Các TList là một loại bạn danh sách nguồn, và E là một loại bạn muốn returned.If kiểu nguồn giống như kiểu trả về, [E] không cần thiết trong mapE, dường như bản đồ func trong kiểu trả về scala là đối tượng.

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