Java 检查映射和返回键中是否存在值或抛出异常

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

我尝试使用Java8流来检查字符串中的所有不同字符是否都存在于映射中,并将它们的键作为列表返回。我可以使用下面的流来完成它:

...
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());