2016-03-19 16 views
6

Tôi khá chắc chắn điều này là không thể trong một dòng, nhưng tôi chỉ muốn kiểm tra:Java Luồng: Tổ chức một bộ sưu tập thành một bản đồ và chọn nhỏ nhất chính

List<WidgetItem> selectedItems = null; 
Map<Integer, List<WidgetItem>> itemsByStockAvailable = WidgetItems.stream() 
    .collect(Collectors.groupingBy(WidgetItem::getAvailableStock)); 
selectedItems = itemsByStockAvailable.get(
    itemsByStockAvailable.keySet().stream().sorted().findFirst().get()); 

Về cơ bản tôi đang thu thập tất cả phụ tùng các mục vào bản đồ trong đó khóa là số lượng availableStock và giá trị là danh sách tất cả các tiện ích có số lượng đó (vì nhiều tiện ích có thể có cùng giá trị). Khi tôi có bản đồ đó, tôi muốn chọn giá trị của bản đồ tương ứng với khóa nhỏ nhất. Bước trung gian của việc tạo Bản đồ là không cần thiết, nó chỉ là cách duy nhất tôi có thể nghĩ đến để làm điều này.

Trả lời

6

Có vẻ như những gì bạn muốn là giữ tất cả các mục tiện ích được nhóm với cổ phiếu có sẵn thấp nhất. Trong trường hợp đó, bạn có thể thu thập các dữ liệu được nhóm vào một TreeMap để đảm bảo trật tự dựa trên giá trị của các cổ phiếu tăng và lấy các mục nhập đầu tiên với firstEntry()

List<WidgetItem> selectedItems = 
    widgetItems.stream() 
       .collect(Collectors.groupingBy(
        WidgetItem::getAvailableStock, 
        TreeMap::new, 
        Collectors.toList() 
       )) 
       .firstEntry() 
       .getValue(); 

Ưu điểm là nó được thực hiện là một vượt qua danh sách ban đầu.

+0

Ah- TreeMap. Tôi quên mất lớp đó vì đã lâu rồi tôi phải sử dụng nó. Cảm ơn! – IcedDante

+3

Nếu bạn muốn nhồi nhét mọi thứ vào một luồng, bạn cũng có thể thực hiện 'Bộ sưu tập. Thu thập và Sau đó (Collectors.groupingBy (...), x -> x.firstEntry(). GetValue())' – user140547

1

Bạn có thể tìm chìa khóa nhỏ nhất trong một đường chuyền đầu tiên và sau đó nhận được tất cả các mục có rằng chìa khóa nhỏ nhất:

widgetItems.stream() 
      .map(WidgetItem::getAvailableStock) 
      .min(Comparator.naturalOrder()) 
      .map(min -> 
       widgetItems.stream() 
          .filter(item -> item.getAvailableStock().equals(min)) 
          .collect(toList())) 
      .orElse(Collections.emptyList()); 
1

Nếu bạn muốn tránh tạo ra các bản đồ trung gian, trước tiên bạn có thể xác định giá trị cổ phiếu nhỏ , lọc theo giá trị đó và thu thập vào danh sách.

int minStock = widgetItems.stream() 
    .mapToInt(WidgetItem::getAvailableStock) 
    .min() 
    .getAsInt(); // or throw if list is empty 

List<WidgetItem> selectItems = widgetItems.stream() 
    .filter(w -> minStock == w.getAvailableStock()) 
    .collect(toList()); 

Ngoài ra, không sử dụng sorted().findFirst() để tìm giá trị tối thiểu của luồng. Sử dụng min để thay thế.

0

tôi sẽ thu thập các dữ liệu vào một NavigableMap, mà chỉ liên quan đến một sự thay đổi nhỏ cho mã ban đầu của bạn:

List<WidgetItem> selectedItems = null; 
NavigableMap<Integer, List<WidgetItem>> itemsByStockAvailable = 
    WidgetItems.stream() 
     .collect(Collectors.groupingBy(WidgetItem::getAvailableStock, 
      TreeMap::new, Collectors.toList())); 
selectedItems = itemsByStockAvailable.firstEntry().getValue(); 
2

Về cơ bản bạn muốn để có được tất cả các yếu tố đầu vào mà là tối thiểu theo quy định của so sánh tùy chỉnh Comparator.comparingInt(WidgetItem::getAvailableStock). Nói chung vấn đề này có thể được giải quyết mà không cần phải lưu trữ mọi thứ vào bản đồ trung gian tạo ra rác không cần thiết. Ngoài ra nó có thể được giải quyết trong một lần. Một số giải pháp thú vị đã có trong câu hỏi this. Ví dụ, bạn có thể sử dụng các nhà sưu tập được thực hiện bởi Stuart Marks:

List<WidgetItem> selectedItems = widgetItems.stream() 
      .collect(maxList(
       Comparator.comparingInt(WidgetItem::getAvailableStock).reversed())); 

nhà sưu tập như vậy là có sẵn trong thư viện StreamEx tôi. Phù hợp nhất trong trường hợp của bạn là MoreCollectors.minAll(Comparator):

List<WidgetItem> selectedItems = widgetItems.stream() 
      .collect(MoreCollectors.minAll(
       Comparator.comparingInt(WidgetItem::getAvailableStock))); 
Các vấn đề liên quan