Java 8中的地图过滤列表



我有一个映射数据结构列表。我需要通过在每个映射中搜索一个值来过滤列表(结果总是只有一个映射(。下面的代码显示了我的两种方法。虽然我的Lambda方法有效,但对我来说似乎有些臃肿。我感觉我在这里错过了一些简单的东西,可以用一个更简洁的Lambda来代替这个。如果有任何建议可以让Lambda变得更好,我将不胜感激。非常感谢。


package test;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class Temp {
public static void main(String[] args) {
Map<String, String> map1 = new HashMap<>();
map1.put("map1-key1", "map1-value-1");
map1.put("map1-key2", "map1-value-2");
map1.put("map1-key3", "map1-value-3");

Map<String, String> map2 = new HashMap<>();
map2.put("map2-key1", "map2-value-1");
map2.put("map2-key2", "some_wanted_value");
map2.put("map2-key3", "map2-value-3");
Map<String, String> map3 = new HashMap<>();
map3.put("map3-key1", "map3-value-1");
map3.put("map3-key2", "map3-value-2");
map3.put("map3-key3", "map3-value-3");
List<Map<String, String>> LOMs = new ArrayList<>();

LOMs.add(map1);
LOMs.add(map2);
LOMs.add(map3);
String column = "some_wanted_value";

// Imperative method.  
Map<String, String> x = new HashMap<>();
for(Map<String, String> lom : LOMs) {
if(lom.containsValue(column)) {
x = lom;
break;
}
}
x.forEach((k,v) -> System.out.println(k + "->" + v));
/*
map2-key1->map2-value-1
map2-key3->map2-value-3
map2-key2->some_wanted_value
*/
// Lambda method.
Map<String, String> y = LOMs
.stream()
.filter(s -> s.containsValue(column))
.flatMap(s -> s.entrySet().stream())
.map(s -> s.toString().split("="))
.collect(Collectors.toMap(s -> s[0], s -> s[1], (o, n) -> o));
y.forEach((k,v) -> System.out.println(k + "->" + v));
/*
map2-key1->map2-value-1
map2-key3->map2-value-3
map2-key2->some_wanted_value
*/
}
}

您只需要将sprint的结果限制为一个结果来匹配您的命令式解决方案,无需通过再次收集来过度复杂化

LOMs.stream()
.filter(s -> s.containsValue(column))
.findFirst()
.orElseGet(Collections::emptyMap)
.forEach((k, v) -> System.out.println(k + "->" + v));

另一种选择是使用ifPresent而不是orElseGet,以确保您不会不必要地实例化地图,这当然取决于您需要什么

LOMs.stream()
.filter(s -> s.containsValue(column))
.findFirst()
.ifPresent(map -> map.forEach((k, v) -> System.out.println(k + "->" + v)));

这与您的命令式解决方案和另一个涉及流的解决方案打印相同的结果

map2-key1->map2-value-1
map2-key3->map2-value-3
map2-key2->some_wanted_value

它应该简单得多:

Map<String, String> result = LOMs.stream()
.filter(map -> map.containsValue(column))
.findFirst() // returns Optional
.get(); // use get if you're sure that you always have one result

如果可能没有结果,请使用Optional#orElse(用于值(或Optional#orElseGet(用于功能接口(。

例如,您可以在此处阅读更多关于Optional的信息。

最新更新