假设我有一个扩展Item的实体Item
和OutOfStockItem
。
我有一个方法basket.getList((,它返回Item
和OutOfStockItems
的列表,我只想从列表中过滤OutOfStockItem
并接收结果:
List<Item>, number of the elements in the left collection
到目前为止,我有一个类似的方法:
return basket.getList().stream()
.filter(OutOfStockItem.class::isInstance)
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
但是它返回Map<项目,长>它将为每个不同的实体返回一个计数器,如:
Item1 = 1;
Item2 = 1;
这是不希望的。可取的采集结果为:
(Item1, Item2; 2)
如果您能就如何实现目标提出建议,我将不胜感激。
不确定为什么需要这样的结果,但一种方法可以是使用Collectors.teeing()
(Java 12或更高版本(
Map<List<Item>,Long> result =
basket.getList().stream()
.filter(OutOfStockItem.class::isInstance)
.collect(
Collectors.teeing(
Collectors.toList(),
Collectors.counting(),
(list, count) -> Map.of(list,count)
));
输出映射(Item1, Item2; 2)
总是只产生一个条目,因此从列表创建条目的解决方案很简单,java流在这里没有带来任何好处。
请记住,以列表为键的地图数据结构是奇怪和不寻常的。
Java 9+
List<Item> items = new ArrayList<>(basket.getList());
items.removeIf(item -> !(item instanceof OutOfStockItem));
Map<List<Item>, Integer>> map = Map.of(items, items.size());
Java 8
List<Item> items = new ArrayList<>(basket.getList());
items.removeIf(item -> !(item instanceof OutOfStockItem));
Map<List<Item>, Integer>> map = new HashMap<>();
map.put(items, items.size());