【问题标题】:Java 8 - How to transform a List of arrays into a List of a specific class objectJava 8 - 如何将数组列表转换为特定类对象的列表
【发布时间】:2015-03-26 03:50:53
【问题描述】:

使用 Java 8 Stream 包,我想将对象类型的数组列表转换为特定类对象的列表。第一个列表中的数组包含从数据库加载的类的字段。

这是从数据库加载的对象类型数组的列表:

List<Object[]> results = loadFromDB();

列表中的每个元素 Object[] 都包含我想要映射到以下类的字段:

class DeviationRisk {
    Timestamp plannedStart;
    Timestamp plannedEnd;
    String rcsName;
    BigDecimal riskValue;
    BigDecimal mediumThreshold;
    BigDecimal highThreshold;
    Interval interval;

    String getRcsName() {
        return rcsName;
    }

    DeviationRisk(Object[] res) {
        this((Timestamp) res[0], (Timestamp) res[1], (String) res[2], (BigDecimal) res[3], (BigDecimal) res[4], (BigDecimal) res[5]);

    }

    DeviationRisk(Timestamp start, Timestamp end, String rcs, BigDecimal risk, BigDecimal medium, BigDecimal high) {
        plannedStart = start;
        plannedEnd = end;
        rcsName = rcs;
        riskValue = risk;
        mediumThreshold = medium;
        highThreshold = high;
        interval = new Interval(plannedStart.getTime(), plannedEnd.getTime());
    }

    DeviationRisk create(Object[] res) {
              return new DeviationRisk(res);
          }

    List<DateTime> getRange() {
        return DateUtil.datesBetween(new DateTime(plannedStart), new DateTime(plannedEnd));
    }
}

您可以看到原始列表results 中存在的每个元素Object[] 它只是对象DeviationRisk 的数组表示

现在,我知道如何使用循环只需 3 行代码,如下所示:

  List<DeviationRisk> deviations = new ArrayList<>();
        for (Object[] res : results) {
            deviations.add(new DeviationRisk(res));
        }

如何使用 Java 8 Streams 实现相同的结果?

【问题讨论】:

    标签: java arrays java-8 lambda java-stream


    【解决方案1】:

    你可以试试:

    List<DeviationRisk> result = results.stream()
                                        .map(DeviationRisk::new)
                                        .collect(Collectors.toList())
    

    【讨论】:

    • 简短而聪明的回答 +1。
    • 干杯 :) 我错过了对 new 的调用。
    • @kocko 你能解释一下它的地图部分吗?当你说 DeviationRisk::new 时会发生什么。我知道这是一个构造函数引用,但是当它被传递一个构造函数引用时,我无法理解 map 方法内部发生的事情。
    • 我可以就转型问题获得您的建议here吗?
    【解决方案2】:

    这样就可以了:

    final List<DeviationRisk> l = results.stream()
        .map(DeviationRisk::new).collect(Collectors.toList());
    

    这项工作是因为DeviationRisk::new 被编译器视为Function&lt;Object[], DeviationRisk&gt;

    【讨论】:

    • 与上面的答案相同,所以你也应该得到 +1 :)
    • @fge 你能解释一下它的地图部分吗?当你说 DeviationRisk::new 时会发生什么。我知道这是一个构造函数引用,但是当它传递给构造函数引用时,我无法理解 map 方法内部发生的事情。
    • @bot 正如我所解释的,这是因为DeviationRisk::new编译器级别被视为Function&lt;Object[], DeviationRisk&gt;。重要的是参数类型 (Object[]) 和返回类型 DeviationRisk。在这种情况下,请忘记 this 是一个构造函数;编译器能够推断出这样一个事实:最终,如果您将 Object[] 传递给 lambda,则结果将是 DeviationRisk。这个特定的 lambda 实际上是对构造函数的方法引用并不重要——它可以是其他任何东西
    • 感谢您的解释。我特别想知道的是map方法是如何使用这个lambda的。例如考虑。 list.stream.map(Apple:new) 被分配给一个字符串列表,Apple 类包含一个初始化 name 实例变量的构造函数。 map 方法如何知道它必须使用 Apple 的名称作为 lambda 的输入,而不是 Apple 中任何其他 String 类型的实例变量。在当前示例中,如果 DeviationRisk 有两个 Object[] 类型的实例变量怎么办? lambda 如何知道使用哪一个作为输入?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-28
    • 2014-12-20
    • 1970-01-01
    • 2012-11-13
    • 1970-01-01
    相关资源
    最近更新 更多