最近我解决了以下问题:
给定按时间顺序排列的LocalDateTime列表,找出邻居之间的平均持续时间。
我做了以下事情:
@Test
public void canCalculateAverageDuration() {
final LocalDateTime now = LocalDateTime.now();
final List<LocalDateTime> localDateTimes = Arrays.asList(now, now.minusHours(5), now.plusMinutes(2));
final List<Duration> durations = new ArrayList<>();
localDateTimes.stream()
.sorted()
.reduce((first, second) -> {
durations.add(Duration.between(first, second));
return second;
});
final OptionalDouble averageNanos = durations.stream()
.mapToDouble(Duration::toNanos)
.average();
final Duration average = Duration.ofNanos((long) averageNanos.orElse(0.0));
assertThat(average).isEqualTo(Duration.parse("PT2H31M"));
}
我想知道问题是否可以以更优雅的方式解决,例如:我想尽可能避免持续时间列表。你觉得怎么样?
答案 0 :(得分:1)
你可以使用迭代解决这个问题(即不使用Streams):
@Test
public void canCalculateAverageDuration() {
final LocalDateTime now = LocalDateTime.now();
final List<LocalDateTime> localDateTimes = Arrays.asList(
now,
now.minusHours(5),
now.plusMinutes(2)
);
localDateTimes.sort(Comparator.naturalOrder());
LocalDateTime previous = null;
LongSummaryStatistics stats = new LongSummaryStatistics();
for (LocalDateTime dateTime : localDateTimes) {
if (previous == null) {
previous = dateTime;
}
else {
stats.accept(Duration.between(previous, dateTime).toNanos());
}
}
final Duration average = Duration.ofNanos((long) Math.ceil(stats.getAverage()));
assertThat(average).isEqualTo(Duration.parse("PT2H31M"));
}
这是否更优雅取决于个人喜好,但此版本至少不使用中间收藏品。
答案 1 :(得分:0)
我刚刚发现了这个:
Collections.sort(localDateTimes);
final double average = IntStream.range(0, localDateTimes.size() - 1)
.mapToLong(l ->
Duration.between(
localDateTimes.get(l),
localDateTimes.get(l+1))
.toNanos())
.average().orElse(0.0);
assertThat(Duration.ofNanos((long) average)).isEqualTo(Duration.parse("PT2H31M"));