【发布时间】:2014-10-02 00:17:57
【问题描述】:
我有一个Set<DateCount>,我使用以下代码创建它。这将创建一组 7 个 DateCount 对象,初始计数为 0,从当天开始,对应于当前周的每一天。
// Create an initial Set of DateCount objects for the current week with counts of 0
Set<DateCount> dateCounts = IntStream.range(0, DAYS_IN_WEEK)
.mapToObj(idx -> new DateTime().withTimeAtStartOfDay().plusDays(idx))
.map(dt -> new DateCount(dt.toDate(), 0L))
.collect(toSet());
我有一个从数据库存储库返回的List<Object[]>。列表中的每个Object[] 在索引0 处都有一个BigDecimal,在索引1 处有一个Long。BigDecimal 实际上是一个日期,类似于20141001。我想知道是否有一种方法可以以流方式使用此数据更新dateCounts 集。现在,我正在执行以下操作,它只是遍历对象数组列表并创建新的DateCount 对象,然后将这些对象添加到dateCounts 集合中。 DateCount 类有一个自定义的equals() 和hashCode() 方法,以确保dateCounts 集在任何给定日期只包含一个DateCount 实例。
data.stream()
.forEach(obj -> {
DateTime date = null;
try {
date = (sdf == null) ? new DateTime(obj[0]) : new DateTime(sdf.parse(obj[0].toString()));
dateCounts.add(new DateCount(date.toDate(), (Long) obj[1]));
} catch (ParseException e) {
e.printStackTrace();
}
});
顺便说一句,我想知道是否还有一种方法可以避免在我的 lambda 表达式中执行 try/catch,只是为了将 String 解析为 Date。
更新 -- 这是我目前为止的想法。尽管在 .map 调用中通过 List<Object[]> 流式传输似乎并不自然,但不确定是否有更好的方法。我介绍了我自己的Tuple<X, Y> 类,因为在没有访问器方法的情况下,在流中使用Object[] 并不能很好地工作。同样在最后两行中,我创建了一个TreeSet 和一个Comparator,以便我可以按日期对数据进行排序。我不觉得这是最好的方法,但我尝试调用 sorted() 并让 DateCount 实现 Comparable 似乎工作正常,但只要调用 collect(toSet()) 方法,排序就会消失.我认为这是流式呼叫的本质。我很好奇是否有办法在调用collect方法之前对其进行排序并在调用collect之后保留排序。
Set<DateCount> dateCounts = IntStream.range(0, DAYS_IN_WEEK)
.mapToObj(idx -> new Tuple<>(new DateTime().withTimeAtStartOfDay().plusDays(idx).toDate(), 0L))
.map(t -> {
Tuple<String, Long> d = data.stream()
.map(arr -> new Tuple<>(arr[0].toString(), (Long) arr[1]))
.filter(tuple -> sdf.format(t.getX()).equals(tuple.getX()))
.findFirst().orElse(new Tuple<>(sdf.format(t.getX()), 0L));
return new DateCount(DateTime.parse(d.getX(), DateTimeFormat.forPattern("yyyyMMdd")).toDate(), d.getY());
})
.collect(toSet());
TreeSet<DateCount> set = new TreeSet<>((a, b) -> a.compareTo(b));
set.addAll(dateCounts);
【问题讨论】:
标签: java lambda java-8 java-stream