Stream Collector.toMap调用toString而不是value

时间:2018-06-13 17:20:58

标签: java java-stream lombok

我一直试图弄清楚为什么这不再有效。它一切正常,没有任何改变与对象或调用它的功能。我使用Lombok作为getter,setter,最初是toString,但我不明白它是如何劫持getter的。我还写了明确的getter来解决问题但无济于事。

@Data
class Engineer {
    private String name;
    private String tech;

    @Override
    public String toString() {
        return "test " + name;
    }
}

使用它的方法

public void example(List<Engineer> engineers) {
    //creates keys with toString and creates duplicates
    Map<String, Engineer> streamMap = engineers.stream().collect(Collectors.toMap(Engineer::getName, Function.identity()));

    //while this one works
    Map<String, Engineer> forLoopMap = new HashMap<>();

    for(Engineer engineer : engineers) {
        forLoopMap.put(engineer.getName, engineer);
    }
}

我通过使用字符串和名称制作自定义toString来解决这个问题。我的原始错误是一个延迟加载问题,因为toString试图获取这些对象。

在我创建自定义toString之后,当我知道名称仍然是唯一的时,它开始给我重复的键错误。

这不仅发生在一个数据列表中,而且发生在单独的实体列表中,也使用不同的唯一标识符。

我一直在使用这种流模式,它工作正常,但现在它有问题。任何想法都将不胜感激。

编辑 - 测试:

  • 明确地将toString(调用getName作为方法引用调用toString)
  • 明确制作getName(最初由Lombok插件生成)
  • 适用于dev配置文件,但不适用于prod配置文件 - 必须是差异

1 个答案:

答案 0 :(得分:0)

您可以为duplicates键提供 BinaryOpearator 的mergeFunction。如果是重复键,最后一个值将被覆盖。

  Map<String, Engineer> streamMap = engineers.stream()
                .collect(Collectors.toMap(Engineer::getName, Function.identity(),
                         (e1, e2) -> {
                            System.out.println("Duplicate key found!"); 
                            return e2;
                         }
                        )
                );