【发布时间】:2019-06-06 10:50:18
【问题描述】:
我有一个具有 (java.util.)Date 属性的项目列表,我想从最早的日期到现在创建一个每天的 DataSeriesItem。它适用于带有时间线的图表系列。
DataSeriesItem 的创建将如下所示:DataSeriesItem seriesItem = new DataSeriesItem(Date, occurrenceCount);
其中occurrenceCount 是其日期属性与当天匹配的项目数。第一个参数的类型也可以是java.time.Instant
我设法找到了一种可行的方法,但我确信我的方法非常很糟糕,可能只需要一个流,也可能是两个。但是,我是流的初学者,以我的知识无法做到。
这可以通过流实现吗? 大概会是什么样子?
我并不是要您重新执行我的整个实现,而只是向我指出您将使用的正确的流函数和映射,并作为奖励积分的示例。
这是我丑陋的解决方案:
List<?> items = myItems;
Collection<Date> foundDates = new HashSet<>();
for (Object item : items) {
foundDates.add((Date)getPropertyValueFromItem(item, configurator.getDateProperty()));
}
//====== This is the part I am asking about ======//
Map<Instant, Integer> foundInstants = new HashMap<>();
foundDates.stream().sorted(Date::compareTo).forEach(date -> {
Calendar c = Calendar.getInstance();
c.clear(); // clear nanoseconds, or else equals won't work!
c.set(date.getYear()+1900, date.getMonth(), date.getDate(), 0, 0, 0);
if(!foundInstants.containsKey(c.toInstant())){
foundInstants.put(c.toInstant(), 1);
} else {
// increment count of that entry
Integer value = foundInstants.get(c.toInstant());
foundInstants.remove(c.toInstant());
foundInstants.put(c.toInstant(), ++value);
}
});
//====== Leaving this code here for context ======//
// Could this maybe simplyfied too by using streams ?
// find oldest date
Date dateIndex = foundDates.stream().min(Date::compareTo).get();
Date now = new Date();
// starting from oldest date, add a seriesItem for each day until now
// if dateOccurrences contains the current/iterated date, use it's value, else 0
while(dateIndex.before(now)){
Calendar c = Calendar.getInstance();
c.clear();// clear nanoseconds, or else equals won't work!
c.set(dateIndex.getYear()+1900, dateIndex.getMonth(), dateIndex.getDate(), 0, 0, 0);
if(foundInstants.containsKey(c.toInstant())){
ExtendedDataSeriesItem seriesItem = new ExtendedDataSeriesItem(c.toInstant(), foundInstants.get(c.toInstant()));
seriesItem.setSeriesType("singleDataPoint");
series.add(seriesItem);
} else {
ExtendedDataSeriesItem seriesItem = new ExtendedDataSeriesItem(c.toInstant(), 0);
seriesItem.setSeriesType("singleDataPoint");
series.add(seriesItem);
}
c.add(Calendar.DATE, 1); // adding a day is complicated. Calendar gets it right. Date does not. This is why I don't use Date here
dateIndex = c.getTime();
}
【问题讨论】:
-
你为什么使用
java.util.Date,你显然是在支持java.time.LocalDate的Java 8上? -
@daniu 我没有做模型。此外,与这个问题完全无关
-
您的问题中的
series是什么? -
@nullpointer 它是一个 DataSeries (com.vaadin.flow.component.charts.model.DataSeries)
标签: java datetime java-8 java-stream