Java 检查映射和返回键中是否存在值或抛出异常
我尝试使用Java8流来检查字符串中的所有不同字符是否都存在于映射中,并将它们的键作为列表返回。我可以使用下面的流来完成它:Java 检查映射和返回键中是否存在值或抛出异常,java,java-8,java-stream,Java,Java 8,Java Stream,我尝试使用Java8流来检查字符串中的所有不同字符是否都存在于映射中,并将它们的键作为列表返回。我可以使用下面的流来完成它: ... map.put("Apple",'a'); map.put("Ball",'b'); map.put("Cat",'c'); map.put("Doll",'d'); String format = "aabbbc"; List<String> li
...
map.put("Apple",'a');
map.put("Ball",'b');
map.put("Cat",'c');
map.put("Doll",'d');
String format = "aabbbc";
List<String> list = format.chars().mapToObj(i -> (char) i).distinct()
.map(c -> map.entrySet().stream()
.filter(entry -> entry.getValue() == c).findFirst().get().getKey())
.collect(Collectors.toList());
但是Java不允许我编译。请帮助我如何处理我的要求
首先,我认为应该抛出
RuntimeException
,而不是Exception
,或者应该在lambda表达式中捕捉到这一点
其次,在使用findFirst
之后,您将得到一个可选的对象,这意味着您应该将结果表单findFirst
映射到map.Entry::getKey
:
List<String> list = format.chars()
.mapToObj(i -> (char) i)
.distinct()
.map(c -> map.entrySet()
.stream()
.filter(entry -> entry.getValue() == c)
.findFirst()
.map(Map.Entry::getKey)
.orElseThrow(() -> new RuntimeException("Character not found in Map")))
.collect(Collectors.toList());
List List=format.chars()
.mapToObj(i->(char)i)
.distinct()
.map(c->map.entrySet()
.stream()
.filter(条目->条目.getValue()==c)
.findFirst()
.map(map.Entry::getKey)
.orelsetrow(()->new RuntimeException(“在映射中找不到字符”))
.collect(Collectors.toList());
传递给映射的lambda表达式是一个函数
,它不允许抛出选中的异常。功能的合同是:
public interface Function<T, R> {
R apply(T t);
}
您还可以创建一个扩展RuntimeException的自定义域异常并抛出该异常
参考资料:
旁注:您正在遍历字符串中每个字符的映射。为了提高性能,您可以创建一个反向映射,以便可以查找(O(1)
)映射中是否存在角色并返回值
List<String> list = format.chars().mapToObj(i -> (char) i).distinct()
.map(c -> {
Optional<Map.Entry<String, Character>> first = map.entrySet().stream().filter(entry -> entry.getValue() == c).findFirst();
if (first.isPresent()) {
return first.get().getKey();
} else {
throw new RuntimeException("Character not found in Map");
}
}).collect(Collectors.toList());
您正在列表中收集结果。但是在引用变量中,您使用了列表
,这就是问题所在。
此外,您正在抛出一个未明确处理的已检查异常。最好使用未检查的异常如RuntimeException.class
上面的答案可以用下面的方式完整地写出来
List<String> list = format.chars().mapToObj(i -> (char) i).distinct()
.map(c -> map.entrySet().stream().filter(entry -> entry.getValue() == c)
.findFirst()
.map(Map.Entry::getKey)
.orElseThrow(RuntimeException::new))
.collect(Collectors.toList());
List List=format.chars().mapToObj(i->(char)i).distinct()
.map(c->map.entrySet().stream().filter(entry->entry.getValue()==c)
.findFirst()
.map(map.Entry::getKey)
.orelsetrow(运行时异常::新建))
.collect(Collectors.toList());
您能解释一下如何将可选的from findFirst()传递给map函数吗?@v1shnu您能解释一下您想要实现什么吗?这对我来说很模糊。这个代码段不符合您的要求吗?请您发布一个示例。是的,我想到了一个反向映射,但我不想创建一个新映射,因为这个查找只在我的应用程序中使用一次。我有一个问题,-为什么第二个。如果在映射中找不到角色,映射不会引发异常?因为我们直接使用方法引用从entry.No中获取密钥。如果字符不在映射中,.map(map.Entry::getKey)
将不会执行,因为没有任何内容会通过过滤器
步骤。明白了。因此,map
将不会被执行,然后findFirst
将成为一个可选的
,因此抛出异常?if(first.isPresent()){return first.get().getKey();
这不是以函数式编写的方法。使用orelsetrow()
.filter(entry -> entry.getValue() == c).findFirst().orElseThrow(()-> new Exception("Character not found in Map"))).collect(Collectors.toList())
List<String> list = format.chars().mapToObj(i -> (char) i).distinct()
.map(c -> map.entrySet().stream().filter(entry -> entry.getValue() == c)
.findFirst()
.map(Map.Entry::getKey)
.orElseThrow(RuntimeException::new))
.collect(Collectors.toList());