2016-11-27 46 views
8

Hãy xem đoạn mã này.Sự khác biệt giữa nhóm và lập bản đồ trong Bộ sưu tập (Java) là gì?

// group by price, uses 'mapping' to convert List<Item> to Set<String> 
    Map<BigDecimal, Set<String>> result = 
      items.stream().collect(
        Collectors.groupingBy(Item::getPrice, 
          Collectors.mapping(Item::getName, Collectors.toSet()) 
        ) 
      ); 

GroupingBy and Mapping hoán đổi cho nhau? Sự khác biệt của họ là gì?

Đối với tham số thứ ba trong tập hợp(), tôi có được cùng kiểu kết xuất Map nếu tôi sử dụng Collectors.toList() thay vì Collectors.toSet()? Tôi nghe nói rằng toList() là một lựa chọn phổ biến hơn.

+0

'toList()' là “phổ biến hơn” ở chỗ nó là mặc định khi không có bộ thu bổ sung nào được chỉ định, tức là 'Collectors.groupingBy (Item :: getPrice)' có cùng kết quả có 'Collectors.groupingBy (Item :: getPrice, Collectors.toList()) '. – Holger

Trả lời

9

GroupingBy and Mapping có thể hoán đổi cho nhau không?

Không, chúng hoàn toàn khác. groupingBy cho phép bạn tạo Map trong đó khóa là đối số đầu tiên được chuyển đến groupingBy và giá trị là List của loại phần tử của Stream.

Collectors.groupingBy(Item::getPrice) sẽ tạo ra một Map<BigDecimal, List<Item>> (giả sử Item::getPrice trả về một BigDecimal. Đi qua các mappingCollector như một cuộc tranh cãi để Collectors.groupingBy() cho phép bạn thay đổi giá trị của bản đồ đầu ra (trong ví dụ của bạn, bạn thay đổi nó để Set<String>).

Đối với tham số thứ ba trong thu thập(), tôi sẽ nhận được cùng một loại sản lượng Map nếu tôi sử dụng Collectors.toList() thay vì Collectors.toSet()?

Không, bạn sẽ nhận được Map<BigDecimal, List<String>>.

+0

Tôi không thể định dạng thông báo lỗi này !! Nếu nhóm bằng cách tạo bản đồ, thì sự khác biệt giữa groupingby và Collectors.toMap() hoặc Collectors.Map() là gì?Bản đồ mapAliasAddress = Files.lines (Paths.get (tên tệp)) .map (s -> s.split (",")) .map (sArr -> new EmailAddress (sArr [1] , sArr [0])) .collect (Collectors.toMap ( email -> email.getAlias ​​(), email -> email )); – NoMoreErrors

+2

@NoMoreErrors 'Collectors.toMap' tạo một' Bản đồ' mà không có nhóm, tức là mỗi phần tử của Luồng đầu vào được ánh xạ tới một Bản đồ đầu ra (giả sử không có khóa trùng lặp). 'groupingBy' ánh xạ nhiều phần tử của luồng đầu vào mà chia sẻ một số thuộc tính vào một Entry duy nhất của Bản đồ đầu ra. – Eran

+0

Vì vậy, tôi có quyền nói rằng Collectors.toMap và Collectors.Mapping là chính xác giống nhau không? – NoMoreErrors

6

Không, cả hai hoàn toàn khác nhau.

Collectors.groupingBy có chức năng tạo khóa và trả về bộ sưu tập trả về bản đồ từ khóa đến bộ sưu tập các đối tượng trong luồng có cùng khóa đó.

Collectors.mapping, mặt khác, có chức năng và bộ sưu tập khác và tạo bộ sưu tập mới trước tiên áp dụng chức năng và sau đó thu thập các phần tử được ánh xạ bằng cách sử dụng các bộ sưu tập đã cho. Như vậy, sau đây là tương đương:

items.stream().map(f).collect(c); 
items.stream().collect(Collectors.mapping(f, c)); 

Collectors.mapping là hữu ích nhất trong tình huống mà bạn không có một dòng suối, nhưng bạn cần phải vượt qua một nhà sưu tập trực tiếp. Một ví dụ về tình huống như vậy là khi sử dụng Collectors.groupingBy.

items.stream().collect(Collectors.groupingBy(Item::getPrice, Collectors.toSet())) 

mang lại một Map<BigDecimal,Set<Item>> (giả sử getPrice() lợi nhuận một BigDecimal). Tuy nhiên,

items.stream().collect(Collectors.groupingBy(Item::getPrice, 
    Collectors.mapping(Item::getName, Collectors.toSet()))) 

trả lại Map<BigDecimal,Set<String>>. Trước khi thu thập các mặt hàng, trước tiên nó áp dụng Item.getName cho chúng.

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