Java 8 Java8流映射-检查所有映射操作是否成功?

Java 8 Java8流映射-检查所有映射操作是否成功?,java-8,java-stream,Java 8,Java Stream,我正在尝试使用streams将一个列表映射到另一个列表 原始列表中的某些元素无法映射。也就是说,映射函数可能无法找到适当的新值 我想知道是否有任何映射失败。理想情况下,一旦发生故障,我也希望停止处理 我目前正在做的是: 如果没有映射值,映射函数将返回null Ifilter()从流中删除空值 Icollect(),然后 我将结果的大小与原始列表的大小进行比较 例如: List<String> func(List<String> old, Map<String,

我正在尝试使用streams将一个列表映射到另一个列表

原始列表中的某些元素无法映射。也就是说,映射函数可能无法找到适当的新值

我想知道是否有任何映射失败。理想情况下,一旦发生故障,我也希望停止处理

我目前正在做的是:

  • 如果没有映射值,映射函数将返回
    null
  • I
    filter()
    从流中删除空值
  • I
    collect()
    ,然后
  • 我将结果的大小与原始列表的大小进行比较
例如:

List<String> func(List<String> old, Map<String, String> oldToNew)
{
    List<String> holger = old.stream()
                          .map(oldToNew::get)
                          .filter(Objects::nonNull)
                          .collect(Collectors.toList);

    if (holger.size() < old.size()) {
       // ... appropriate error handling code ... 
    }
    else {
       return holger;
    }
}
List func(列表旧、映射旧、映射新)
{
List holger=old.stream()
.map(oldToNew::get)
.filter(对象::非空)
.collect(收集器.toList);
if(holger.size()
这不是很优雅。而且,即使整件事情都失败了,所有的事情都会得到处理

关于更好的方法的建议?
或者我应该完全抛弃流,使用好的旧循环?

您可以将过滤器更改为
对象::requirennoull
并捕获流外部的NullPointerException

没有最佳解决方案,因为这在很大程度上取决于用例。例如,如果预计查找失败的可能性不大,或者错误处理意味着无论如何都会引发异常,那么在映射函数中第一次失败的查找时引发异常确实是一个不错的选择。然后,后续代码不必关心错误条件

另一种处理方法可能是:

List<String> func(List<String> old, Map<String, String> oldToNew) {
    Map<Boolean,List<String>> map=old.stream()
        .map(oldToNew::get)
        .collect(Collectors.partitioningBy(Objects::nonNull));
    List<String> failed=map.get(false);
    if(!failed.isEmpty())
        throw new IllegalStateException(failed.size()+" lookups failed");
    return map.get(true);
}

它收集两个有意义的列表,其中包含失败查找的失败键和成功映射值的列表。请注意,这两个列表都可以返回。

如果结果为空,为什么不从
oldToNew::get
中抛出一个未经检查的异常,并在外部捕获它?@Tunaki谢谢,这是一个选项。我不知道这是否会提高优雅性或性能(因为异常被认为是昂贵的)。不要将变量命名为
new
。这行不通……那么
void List
的返回类型应该是什么意思呢?@Holger,我希望你更喜欢这个新名称,至少它是一个合法的名称,尽管在代码的上下文中不是一个有意义的名称。捕获
NullPointerException
从来都不是一个好主意。我不建议这样做。
List<String> func(List<String> old, Map<String, String> oldToNew) {
    Map<Boolean,List<String>> map=old.stream()
        .map(s -> new AbstractMap.SimpleImmutableEntry<>(s, oldToNew.get(s)))
        .collect(Collectors.partitioningBy(e -> e.getValue()!=null,
            Collectors.mapping(e -> Optional.ofNullable(e.getValue()).orElse(e.getKey()),
                Collectors.toList())));
    List<String> failed=map.get(false);
    if(!failed.isEmpty())
        throw new IllegalStateException("The following key(s) failed: "+failed);
    return map.get(true);
}