【问题标题】:Java 8 - Update two properties in same Stream codeJava 8 - 更新同一流代码中的两个属性
【发布时间】:2021-07-30 19:25:54
【问题描述】:

我想知道是否有一种方法可以在 Stream lambda 代码中更新两次对象,我需要更新一个类的两个属性,我需要更新 valuerecordsCount属性

对象:

public class HistoricDataModelParsed {

private Date   startDate;
private Date   endDate;
private Double value;
private int    recordsCount;

}

我试着做这样的事情:

val existingRecord = response.stream()
     .filter(dateTime ->fromDate.equals(dateTime.getStartDate()))
     .findAny()
     .orElse(null);


response.stream()
     .filter(dateTime ->fromDate.equals(dateTime.getStartDate()))
     .findAny()
     .orElse(existingRecord)
     .setValue(valueAdded)
     .setRecordsCount(amount);

但我收到了这个错误:“无法在原始类型 void 上调用 setRecordsCount(int)

所以我最终做了两次流来更新我需要的两个字段中的每一个

response.stream()
     .filter(dateTime ->fromDate.equals(dateTime.getStartDate()))
     .findAny()
     .orElse(existingRecord)
     .setValue(valueAdded);
                
 response.stream()
     .filter(dateTime ->fromDate.equals(dateTime.getStartDate()))
     .findAny()
     .orElse(existingRecord)
     .setRecordsCount(amount);      

有没有一种方法可以实现我所需要的而不需要流两次列表?

【问题讨论】:

  • 你不应该使用Date
  • existingRecord 到底是什么?
  • @MCEmperor 你能详细说明原因吗?
  • @MohamedAneesA 更新了问题以添加该变量是什么
  • @xThunder 当然。 Here is something。此外,新的 API(在 java.time 包中)更加完整,因为它还 models concepts 在旧 API 中不可用,如周期和持续时间。

标签: java java-8 java-stream


【解决方案1】:

setValue 的返回类型是void不是 HistoricDataModelParsed。所以你不能调用setRecordsCount类中的方法HistoricDataModelParsed

您可以在HistoricDataModelParsed 中添加一个方法,该方法接受valuerecordsCount 的两个参数:

public void setValueAndCount(Double value, int count) {
    this.value = value;
    this.recordsCount = count;
}

然后在orElse之后调用这个方法:

response.stream()
     .filter(dateTime ->fromDate.equals(dateTime.getStartDate()))
     .findAny()
     .orElse(existingRecord)
     .setValueAndCount(valueAdded, amount);

【讨论】:

    【解决方案2】:

    对象的状态不应在流中改变。它可能导致不一致的结果。但是您可以创建对象的新实例并通过构造函数传递新值。这是一个演示该方法的简单记录。记录基本上是不可变的类,没有设置器。 getter 是变量的名称。一个类也可以在这个例子中工作。

    record Temp(int getA, int getB) {
        @Override
        public String toString() {
            return "[" + getA + ", " + getB  +"]";
        }
    }
    

    一些数据

        List<Temp> list = List.of(new Temp(10, 20), new Temp(50, 200),
            new Temp(100, 200));
    

    还有转型。带有新值的Temp 的新实例与旧值一起创建,以完全填充构造函数。否则,将传递现有对象。

    List<Temp> result = list.stream().map(
            t -> t.getA() == 50 ? new Temp(2000, t.getB()) : t)
            .toList();
    
    System.out.println(result);
    

    打印

    [[10, 20], [2000, 200], [100, 200]]
    

    要回答您得到的void 错误,这是因为流期望值继续通过流,因此如果方法无效,则它不会返回任何内容,因此您必须返回它。这是一个例子:

    stream.map(t->{voidReturnMethod(t); return t;}).toList();
    

    返回确保管道继续。

    【讨论】:

      【解决方案3】:

      只需存储orElse 的结果,然后在其上调用您的方法。

      HistoricDataModelParsed record = 
          response.stream()
              .filter(dateTime -> fromDate.equals(dateTime.getStartDate()))
              .findAny()
              .orElse(existingRecord);
      
      record.setValue(valueAdded)
      record.setRecordsCount(amount);
      

      【讨论】:

        猜你喜欢
        • 2018-09-08
        • 2017-07-12
        • 1970-01-01
        • 2017-06-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-12-21
        相关资源
        最近更新 更多