我很确定这行不可能,但我只想查一下:
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());
基本上我将所有小部件项目收集到地图中,其中关键字是可用的库存数量,值是具有该数量的所有小部件的列表(因为多个小部件可能具有相同的值)。一旦我有了这张地图,我就想选择与最小键对应的地图值。创建地图的中间步骤是不必要的,这是我能想到的唯一方法。
答案 0 :(得分:6)
您希望保留所有以最低可用库存分组的窗口小部件项目。在这种情况下,您可以将分组数据收集到TreeMap
中,以确保根据库存值的增加进行排序,并使用firstEntry()
检索第一个条目
List<WidgetItem> selectedItems =
widgetItems.stream()
.collect(Collectors.groupingBy(
WidgetItem::getAvailableStock,
TreeMap::new,
Collectors.toList()
))
.firstEntry()
.getValue();
优点是它完成了初始列表的一次传递。
答案 1 :(得分:2)
基本上,您希望根据自定义比较器Comparator.comparingInt(WidgetItem::getAvailableStock)
获取最小的所有输入元素。通常,这个问题可以解决而无需将所有内容存储到中间映射中,从而产生不必要的垃圾。它也可以单程解决。 this问题中已经存在一些有趣的解决方案。例如,您可以使用Stuart Marks实现的收集器:
List<WidgetItem> selectedItems = widgetItems.stream()
.collect(maxList(
Comparator.comparingInt(WidgetItem::getAvailableStock).reversed()));
我的StreamEx图书馆随时可以使用这些收藏家。最适合您的情况是MoreCollectors.minAll(Comparator)
:
List<WidgetItem> selectedItems = widgetItems.stream()
.collect(MoreCollectors.minAll(
Comparator.comparingInt(WidgetItem::getAvailableStock)));
答案 2 :(得分:1)
您可以在第一遍中找到最小的密钥,然后获取具有该最小密钥的所有项目:
widgetItems.stream()
.map(WidgetItem::getAvailableStock)
.min(Comparator.naturalOrder())
.map(min ->
widgetItems.stream()
.filter(item -> item.getAvailableStock().equals(min))
.collect(toList()))
.orElse(Collections.emptyList());
答案 3 :(得分:1)
如果您想避免创建中间地图,您可以先确定最小的库存值,按该值过滤并收集到列表。
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());
另外,请勿使用sorted().findFirst()
来查找流的最小值。请改用min
。
答案 4 :(得分:0)
我会将数据收集到NavigableMap中,只需对原始代码进行一些小改动:
List<WidgetItem> selectedItems = null;
NavigableMap<Integer, List<WidgetItem>> itemsByStockAvailable =
WidgetItems.stream()
.collect(Collectors.groupingBy(WidgetItem::getAvailableStock,
TreeMap::new, Collectors.toList()));
selectedItems = itemsByStockAvailable.firstEntry().getValue();