【问题标题】:Java 8 Map a List to another list and countJava 8 将一个列表映射到另一个列表并计数
【发布时间】:2018-04-21 09:38:02
【问题描述】:

我希望为现有列表创建一个历史值列表,以便我可以将其保存在数据库中以便稍后在表格中显示

Class Data {
  Date date;
  int int1;
  int int2;
}

class DataHistory {
  Date date;
   int sum_Int1_beforeOrEqualDate;
   int sum_Int2_beforeOrEqualDate;
   String someOtherValues;
}

例如,我有几行 perDate 包含所有值。我想要实现的是:

我的意见:

date,    int1,  int2
01/01/18,  2,    3
01/01/18,  0,    1
02/01/18,  0,    1
02/01/18,  3,    0
03/01/18,  1,    3
...

我的输出:

date,    sum_Int1_beforeOrEqualDate,  sum_Int2_beforeOrEqualDate
01/01/18,  2,    4
02/01/18,  3,    1
03/01/18,  1,    3
...

我尝试了几件事,主要是使用 Map,但从未能够使用 List-->List 做到这一点。

我尝试做的是:

编辑:我的最后一次尝试,清楚地表明我不知道自己在做什么..

List<OutputList> outputList =
inputlist
.stream()
.map( e -> new DataHistory())
.collect(Collectors.groupingBy(int1));

【问题讨论】:

  • 展示您尝试过的内容以更好地说明您的描述。
  • 这两个总和字段将如何计算?
  • 您将如何提供输入,通过控制台一一输入值或通过文件提供输入?
  • 我的输入值来自数据库中的数据实体。 @Aris :它只是之前或相等日期之前所有先前值的总和
  • 我的第一步是抛弃过时的Date 类,并从java.time 引入LocalDatejava.time 是现代 Java 日期和时间 API,使用起来更方便。一个Date尽管它的名字是一个毫秒精度的时间点,所以在同一日期有很多,这可能会给过滤带来麻烦。

标签: java arrays date arraylist java-stream


【解决方案1】:

我相信您只是想简单地将按日期分组的值相加。因此,假设您已将数据解析为列表

List<Data> list = getDataAsList();
List<DataHistory> historyList = list.stream()
            .collect(Collectors.groupingBy(data -> data.date)).entrySet().stream()
            .map((entry) -> {
                DataHistory history = new DataHistory();
                history.date = entry.getKey();
                List<Data> dataList = entry.getValue();
                history.sum_Int1_beforeOrEqualDate = dataList.stream().mapToInt(data -> data.int1).sum();
                history.sum_Int2_beforeOrEqualDate = dataList.stream().mapToInt(data -> data.int2).sum();
                return history;
            })
            .collect(Collectors.toList());

如果我的逻辑正确,请告诉我。

【讨论】:

  • 而不是遍历dataList 两次来获得总和,您可以像for (Data data : dataList){ history.sum_Int1_beforeOrEqualDate += data.int1; history.sum_Int2_beforeOrEqualDate += data.int2; } 那样一次性完成。
【解决方案2】:

你可以做的是使用Collections.reducing,效果很好。

List<DataHistory> dataHistories = 
                   list.stream()
                       .collect(Collectors.groupingBy(Data::getDate, 
                                Collectors.reducing(DataHistory::new,
                                                    DataHistoryHelper::merge)))
                       .values();

此解决方案假定您在 DataHistory 中有一个以 Data 作为参数的构造函数。

public DataHistory(Data o) {
    this.date = o.getDate();
    // and so on
}

而且你有一个方法(在任何地方)可以合并两个 DataHistory 对象

public DataHistory merge(DataHistory o1, DataHistory o2) {
    DataHistory merged = new DataHistory();
    merged.setSum_Int1_beforeOrEqualDate(o1.getSum_Int1_beforeOrEqualDate + o2.getSum_Int1_beforeOrEqualDate);
    // and so on
    return merged;
}

【讨论】:

    【解决方案3】:

    您可以使用toMap 收集器完成手头的任务:

    Collection<DataHistory> resultSet = 
             myList.stream()
                   .collect(Collectors.toMap(Data::getDate,
                            e -> new DataHistory(e.getDate(), e.getInt1(), e.getInt2(), null),
                            DataHistory::merge)).values();
    

    这假设您在 DataHistory 类中定义了如下构造函数:

    public DataHistory(Date date, int sum_Int1_beforeOrEqualDate, 
              int sum_Int2_beforeOrEqualDate, String someOtherValues) {
            this.date = date;
            this.sum_Int1_beforeOrEqualDate = sum_Int1_beforeOrEqualDate;
            this.sum_Int2_beforeOrEqualDate = sum_Int2_beforeOrEqualDate;
            this.someOtherValues = someOtherValues;
    }
    

    还有一个 merge 函数定义如下:

    public DataHistory merge(DataHistory other){
            this.sum_Int1_beforeOrEqualDate += other.getSum_Int1_beforeOrEqualDate();
            this.sum_Int2_beforeOrEqualDate += other.getSum_Int2_beforeOrEqualDate();
            return this;
    }
    

    DataHistory 类中。


    此外,如果您明确需要 List&lt;DataHistory&gt; 而不是 Collection&lt;DataHistory&gt;,那么您可以这样做:

     List<DataHistory> historyList = new ArrayList<>(resultSet); 
    

    请注意,我将 null 传递给 DataHistory 构造函数的第四个参数只是因为我不知道要传递什么数据,所以我将把它留给你决定。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多