【问题标题】:Streaming over a Java list to populating a Map通过 Java 列表流式传输以填充 Map
【发布时间】:2021-12-08 16:08:49
【问题描述】:

这里是 Java 11。我有以下 POJO:

@Data // Lombok; adds getters, setters, all-args constructor and equals and hashCode
public class Fliflam {
    private String merf;
    private String tarf;
    private Boolean isFlerf;
}

我有一个方法可以验证Flimflam 并返回验证Flimflam 时遇到的任何错误的List<String>。如果有人出于某种原因认为这有帮助,我可以将其更改为返回 Optional<List<String>>,尤其是在处理 Stream API 时:

public List<String> validateFlimflam(Flimflam flimflam) {
    List<String> errors = new ArrayList<>();

    // ... validation code omitted for brevity
    // 'errors' list is populated with any errors; otherwise it returns empty

    return errors;
}

我想通过List&lt;Flimflam&gt; 流式传输(Stream API)并填充Map&lt;Flimflam,List&lt;String&gt;&gt; 错误映射,其中映射的键是验证失败的Flimflam,其对应的value 是验证错误字符串的列表。

我可以像这样以“老式”的方式实现这一点:

List<Flimflam> flimflams = getSomehow();
Map<Flimflam,List<String>> errorsMap = new HashMap<>();
for (Flimflam ff : flimflams) {
    List<String> errors = validateFlimflam(ff);
    if (!errors.isEmpty() {
        errorsMap.put(ff, errors);
    }
}

如何通过 Stream API 完成此操作?

【问题讨论】:

  • 使用 Vavr Validation 是否更有意义?
  • @hotmeatballsoup 实际上,它没有。它没有指定validateFlimflam 方法的声明位置(尽管可以推测)。确切地知道如何应用任何 lambda 或方法引用非常重要。奇怪的是,接受的答案不起作用,因为它在语法上不正确。但我没有投反对票。
  • 那么您或其他人可能会提出要求,并让我有机会添加更多细节。值得深思。

标签: java java-stream


【解决方案1】:

像这样

Map<Flimflam,List<String>> errorsMap = flimflams.stream().collect(Collectors.toMap(f -> f, f-> f::validateFlimflam));

toMap 接受 2 个参数(keyMapper,valueMapper) 在您的情况下,键映射器是来自流本身的对象,而值是在该对象上调用 validateFlimflam

【讨论】:

    【解决方案2】:

    很难说你的validateFlimflam 方法是在哪里定义的。我怀疑它不在Flimflam 类本身中,因为不需要将自身的实例传递给方法。所以我认为它是该类的外部方法。假设我将按以下方式进行:

    thisClass = 包含validateFlimflam 的实例。可以设置为this

    Map<Flimflam, List<String>> errorsMap =
            flimflams.stream().collect(Collectors.toMap(f -> f,
                            thisClass::validateFlimflam));
    

    如果碰巧Flimflam 确实包含validateFlimflam,您可以这样做。请注意,这假定该方法采用 无参数,因为它们不是必需的

    Map<Flimflam, List<String>> errorsMap =
            flimflams.stream().collect(Collectors.toMap(f -> f,
                            Flimflam::validateFlimflam));
    

    最后,如果包含类是某个其他类并且validateFlimflam 方法被声明为静态,那么您可以通过使用包含类名称不是实例来这样做。此外,在这种情况下,该方法将采用定义的参数。

    Map<Flimflam, List<String>> errorsMap =
            flimflams.stream().collect(Collectors.toMap(f -> f,
                            SomeClass::validateFlimflam));
     
    

    【讨论】:

      猜你喜欢
      • 2012-02-11
      • 2015-09-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多