Java8将一个列表映射到另一个列表并计数
我希望为现有列表创建一个历史值列表,以便将其保存在DB中,以便稍后在表中显示Java8将一个列表映射到另一个列表并计数,java,arrays,date,arraylist,java-stream,Java,Arrays,Date,Arraylist,Java Stream,我希望为现有列表创建一个历史值列表,以便将其保存在DB中,以便稍后在表中显示 Class Data { Date date; int int1; int int2; } class DataHistory { Date date; int sum_Int1_beforeOrEqualDate; int sum_Int2_beforeOrEqualDate; String someOtherValues; } 例如,我每个日期有几行包含所有值。我希望达到的目标
Class Data {
Date date;
int int1;
int int2;
}
class DataHistory {
Date date;
int sum_Int1_beforeOrEqualDate;
int sum_Int2_beforeOrEqualDate;
String someOtherValues;
}
例如,我每个日期有几行包含所有值。我希望达到的目标是:
我的意见:
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));
列表输出列表=
输入列表
.stream()
.map(e->new DataHistory())
.collect(收集器.groupingBy(int1));
我相信您只是在尝试按日期对分组的值求和。因此,假设您已将数据解析为列表
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());
List List=getDataAsList();
List historyList=List.stream()
.collect(Collectors.groupingBy(data->data.date)).entrySet().stream()
.map((条目)->{
DataHistory history=新的DataHistory();
history.date=entry.getKey();
List dataList=entry.getValue();
history.sum\u Int1\u beforeQualdate=dataList.stream().mapToInt(data->data.Int1.sum();
history.sum\u Int2\u beforeQualdate=dataList.stream().mapToInt(data->data.Int2.sum();
回归历史;
})
.collect(Collectors.toList());
告诉我我的逻辑是否正确。我相信您只是在尝试按日期对分组的值求和。因此,假设您已将数据解析为列表
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());
List List=getDataAsList();
List historyList=List.stream()
.collect(Collectors.groupingBy(data->data.date)).entrySet().stream()
.map((条目)->{
DataHistory history=新的DataHistory();
history.date=entry.getKey();
List dataList=entry.getValue();
history.sum\u Int1\u beforeQualdate=dataList.stream().mapToInt(data->data.Int1.sum();
history.sum\u Int2\u beforeQualdate=dataList.stream().mapToInt(data->data.Int2.sum();
回归历史;
})
.collect(Collectors.toList());
告诉我逻辑是否正确。您可以使用
toMap
收集器完成手头的任务:
Collection<DataHistory> resultSet =
myList.stream()
.collect(Collectors.toMap(Data::getDate,
e -> new DataHistory(e.getDate(), e.getInt1(), e.getInt2(), null),
DataHistory::merge)).values();
以及一个定义如下的合并
函数:
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<DataHistory> historyList = new ArrayList<>(resultSet);
List historyList=new ArrayList(resultSet);
请注意,我正在将第四个参数的
null
传递给DataHistory
构造函数,原因很简单,因为我不知道传递什么数据,所以我将留给您决定。您可以使用toMap
收集器完成手头的任务:
Collection<DataHistory> resultSet =
myList.stream()
.collect(Collectors.toMap(Data::getDate,
e -> new DataHistory(e.getDate(), e.getInt1(), e.getInt2(), null),
DataHistory::merge)).values();
以及一个定义如下的合并
函数:
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<DataHistory> historyList = new ArrayList<>(resultSet);
List historyList=new ArrayList(resultSet);
请注意,我正在将第四个参数的
null
传递给DataHistory
构造函数,原因很简单,因为我不知道要传递什么数据,所以我将把它留给您来决定。您可以做的是使用集合。减少效果非常好
List<DataHistory> dataHistories =
list.stream()
.collect(Collectors.groupingBy(Data::getDate,
Collectors.reducing(DataHistory::new,
DataHistoryHelper::merge)))
.values();
您有一个方法(任何地方)负责合并两个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;
}
你能做的就是使用集合。减少,效果很好
List<DataHistory> dataHistories =
list.stream()
.collect(Collectors.groupingBy(Data::getDate,
Collectors.reducing(DataHistory::new,
DataHistoryHelper::merge)))
.values();
您有一个方法(任何地方)负责合并两个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;
}
显示您试图更好地说明您的描述的内容。两个总和字段将如何计算?您将如何通过控制台逐个输入值或通过文件提供输入?我的输入值来自数据库中的数据实体@Aris:它只是Date之前或之前所有值的总和。我的第一步是扔掉过时的Date
类,从java.time
引入LocalDate
java.time
是现代的java日期和时间API,使用起来更方便。Date
尽管它的名称是毫秒精度的时间点,但是在同一个日期有很多,这可能会在筛选过程中造成问题。展示您试图更好地说明您的描述的内容。如何计算两个总和字段?您将如何提供输入,通过控制台逐个输入值或通过文件提供输入?我的输入值来自数据库中的数据实体@Aris:它只是Date之前或之前所有值的总和。我的第一步是扔掉过时的Date
类,从java.time
引入LocalDate
java.time
是现代的java日期和时间API,使用起来更方便。Date
尽管它的名称是一个毫秒精度的时间点,但是在同一个日期上有很多,这可能会在过滤过程中造成麻烦。与遍历dataList
两次以获取总和不同,您可以像for(Data Data Data:dataList)那样一次性完成{history.sum_Int1_beforeQualdate+=data.Int1;history.sum_Int2_beforeQualdate+=data.Int2;}
而不是遍历dataList
两次以获得总和,您可以像(data-data:dataList)那样一次性完成{history.sum_Int1_beforeQualdate+=data.Int1;history.sum_Int2_beforeQualdate+=data.Int2;}