Java 8中的地图筛选列表
我有一个地图数据结构列表。我需要通过在每个映射中搜索一个值来过滤列表(结果总是只有一个映射)。下面的代码显示了我的两种方法。虽然我的Lambda方法有效,但对我来说似乎过于臃肿。我感觉这里缺少了一些简单的东西,可以用一个更简洁的Lambda来代替这个。如果您能给我一些建议,让Lambda更好,我将不胜感激。多谢Java 8中的地图筛选列表,java,list,java-stream,maps,Java,List,Java Stream,Maps,我有一个地图数据结构列表。我需要通过在每个映射中搜索一个值来过滤列表(结果总是只有一个映射)。下面的代码显示了我的两种方法。虽然我的Lambda方法有效,但对我来说似乎过于臃肿。我感觉这里缺少了一些简单的东西,可以用一个更简洁的Lambda来代替这个。如果您能给我一些建议,让Lambda更好,我将不胜感激。多谢 package test; import java.util.ArrayList; import java.util.HashMap; import java.util.List;
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
*/
}
}
包装试验;
导入java.util.ArrayList;
导入java.util.HashMap;
导入java.util.List;
导入java.util.Map;
导入java.util.stream.collector;
公共类临时工{
公共静态void main(字符串[]args){
Map map1=新的HashMap();
map1.put(“map1-key1”、“map1-value-1”);
map1.put(“map1-key2”、“map1-value-2”);
map1.put(“map1-key3”、“map1-value-3”);
Map map2=新的HashMap();
map2.put(“map2-key1”、“map2-value-1”);
map2.put(“map2-key2”,“某些需要的值”);
map2.put(“map2-key3”、“map2-value-3”);
Map map3=新的HashMap();
map3.put(“map3-key1”、“map3-value-1”);
map3.put(“map3-key2”、“map3-value-2”);
map3.put(“map3-key3”、“map3-value-3”);
列表LOMs=新的ArrayList();
LOMs.add(map1);
LOMs.add(map2);
LOMs.add(map3);
String column=“some\u wanted\u value”;
//命令式方法。
Map x=新的HashMap();
用于(地图lom:LOMs){
if(lom.包含值(列)){
x=lom;
打破
}
}
x、 forEach((k,v)->System.out.println(k+“->”+v));
/*
map2-key1->map2-value-1
map2-key3->map2-value-3
map2-key2->一些需要的值
*/
//Lambda法。
映射y=LOMs
.stream()
.filter(s->s.containsValue(列))
.flatMap(s->s.entrySet().stream())
.map(s->s.toString().split(“”)
.collect(收集器.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->一些需要的值
*/
}
}
您只需将sprint的结果限制为一个结果,以匹配您的命令式解决方案,而无需通过再次收集来使其过于复杂
LOMs.stream()
.filter(s->s.containsValue(列))
.findFirst()
.orElseGet(集合::清空映射)
.forEach((k,v)->System.out.println(k+“->”+v));
另一种方法是使用ifPresent
而不是orElseGet
,以确保不会不必要地实例化地图,这当然取决于您需要什么
LOMs.stream()
.filter(s->s.containsValue(列))
.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 result=LOMs.stream()
.filter(映射->映射.containsValue(列))
.findFirst()//返回可选的
.get();//如果您确信总是有一个结果,请使用get
如果可能没有结果,请使用Optional#orElse
(用于值)或Optional#orElseGet
(用于功能接口)
您可以阅读更多关于可选的信息,例如,.使用
get()
是一种反模式。不幸的是,请尝试orElse
/orElseGet
或如果存在
谢谢,Yassin。这两个选项都很好,而且比原来的Lambda有了很大的改进。欢迎@Jack随意投票/接受答案,以结束这个问题,并让问题变得明显。这个答案帮助了你。谢谢,Yassin。我投了赞成票。因为我的代表只在11点,所以upvote会被记录但不会显示。很抱歉。@Jack没问题,通常即使有11分也可以接受答案,这已经有助于结束问题