Java 8 - 如何将一个数组列表转换为特定类对象的列表

9
使用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实现相同的结果?

2个回答

19

您可以尝试:

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

short and smart answer +1. - atish shimpi
我错过了调用 new 的语句。 - Alboz
@kocko,你能解释一下它的map部分吗?当你说DeviationRisk::new时会发生什么?我知道这是一个构造函数引用,但当它传递一个构造函数引用到map方法中时,我无法理解其中发生了什么。 - Chetan Kinger
请问您能否在这里(http://stackoverflow.com/questions/29948117/how-to-transform-a-nested-list-of-double-into-a-java-class)给我提供一下转换问题的建议?谢谢。 - JJD

7
这将做到它:
final List<DeviationRisk> l = results.stream()
    .map(DeviationRisk::new).collect(Collectors.toList());

这是因为编译器将DeviationRisk::new视为一个Function<Object[], DeviationRisk>


请提供需要翻译为中文的编程内容。 - Alboz
@fge,你能解释一下代码中的map部分吗?当你调用DeviationRisk::new时会发生什么?我知道这是一个构造函数引用,但当它被传递给map方法时,我无法理解其中发生了什么。 - Chetan Kinger
@bot 正如我所解释的那样,这是因为在编译器级别上,DeviationRisk::new 被视为 Function<Object[], DeviationRisk>。重要的是参数类型(Object[])和返回类型DeviationRisk。在这种情况下,只需忘记这是一个构造函数即可;如果您将某个是 Object[] 的东西传递给 lambda,编译器能够推断出结果将是 DeviationRisk。这个特定的 lambda 实际上是对构造函数的方法引用并不重要——它可以是任何其他东西。 - fge
谢谢解释。我想要具体了解的是map方法如何使用这个lambda表达式。例如,.list.stream.map(Apple:new)被分配给一个字符串列表和Apple类包含一个初始化名称实例变量的构造函数。map方法如何知道它必须使用Apple的名称作为lambda的输入,而不是Apple中类型为String的任何其他实例变量。在当前示例中,如果DeviationRisk有两个类型为Object []的实例变量怎么办?lambda如何知道使用哪一个作为输入? - Chetan Kinger

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接