我有一个地图,其中值是字符串,键是列表:Map<String, List<BoMLine>> materials.我想用它的值过滤这个地图; 这样的事情:
materials.entrySet().stream()
.filter(a->a.getValue().stream()
.filter(l->MaterialDao.findMaterialByName(l.getMaterial()).ispresent)
Run Code Online (Sandbox Code Playgroud)
但这对我不起作用.有人有想法吗?
谢谢.
Era*_*ran 29
如果我正确理解了您的过滤条件,您需要检查Stream从该值生成的过滤是否List包含任何元素,如果是,则将相应的Map条目传递给输出Map.
Map<String, List<BoMLine>>
filtered = materials.entrySet()
.stream()
.filter(a->a.getValue()
.stream()
.anyMatch(l->MaterialDao.findMaterialByName(l.getMaterial())))
.collect(Collectors.toMap(e->e.getKey(),e->e.getValue()));
Run Code Online (Sandbox Code Playgroud)
假设MaterialDao.findMaterialByName(l.getMaterial())返回a boolean.
Mat*_*aun 18
通常,您可以按照其值过滤地图:
static <K, V> Map<K, V> filterByValue(Map<K, V> map, Predicate<V> predicate) {
return map.entrySet()
.stream()
.filter(entry -> predicate.test(entry.getValue()))
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
}
Run Code Online (Sandbox Code Playgroud)
像这样称呼它:
Map<String, Integer> originalMap = new HashMap<>();
originalMap.put("One", 1);
originalMap.put("Two", 2);
originalMap.put("Three", 3);
Map<String, Integer> filteredMap = filterByValue(originalMap, value -> value == 2);
Map<String, Integer> expectedMap = new HashMap<>();
expectedMap.put("Two", 2);
assertEquals(expectedMap, filteredMap);
Run Code Online (Sandbox Code Playgroud)
以前的所有答案都提供了一个解决方案,可以创建一个新的Map. 如果您只想删除几个条目,这可能效率低下。
以下内容从现有 中 删除元素Map:
Map<String, Integer> myMap = new HashMap<>();
myMap.put("One", 1);
myMap.put("Two", 2);
myMap.put("Three", 3);
myMap.keySet().removeAll(
myMap.entrySet().stream()
.filter(a->a.getValue().equals(2))
.map(e -> e.getKey()).collect(Collectors.toList()));
System.out.println(myMap);
Run Code Online (Sandbox Code Playgroud)
印刷:
Map<String, Integer> myMap = new HashMap<>();
myMap.put("One", 1);
myMap.put("Two", 2);
myMap.put("Three", 3);
myMap.keySet().removeAll(
myMap.entrySet().stream()
.filter(a->a.getValue().equals(2))
.map(e -> e.getKey()).collect(Collectors.toList()));
System.out.println(myMap);
Run Code Online (Sandbox Code Playgroud)
它是如何工作的?它将所有需要删除的密钥收集到一个临时 中List,然后Map一次性将它们从原始密钥中删除。临时List是必需的,因为修改 aMap会使流和迭代器无效。但是,Map与构建List.
如果您想删除大量条目(50% 或更多),那么最好Map确实构建一个新条目。