如何将参数发送到流中的引用方法(java 8)?
我有一个活动列表(活动),我想确定一个Map(String, DateTime)
的表格Map(String, DateTime)
(不是Duration或Period;它是必须的Map(String, DateTime)
的数据结构。 对于每个活动,在监测期间计算的总持续时间。
Activity类有: activityLabel(String)
, startTime(DateTime)
, endTime(DateTime)
。 我用joda
时间。 这就是我所做的:
Map durations = activities.stream().collect(Collectors.toMap( it -> it.activityLabel, it ->new DateTime(0,0,0,0,0,0) //,DateTime::plus ));
我想我应该使用DateTime plus(ReadablePeriod period)或DateTime plus(ReadableDuration duration) ,但我不知道如何将类型为Duration或Period的参数发送到方法引用。
我怎样才能达到这个效果?
编辑:输入:
2011-12-03 01:00:00 2011-12-03 9:00:00睡觉
2011-12-04 03:00:00 2011-12-04 10:30:00睡觉
我应该有输出:睡觉0-0-0 15:30:00(年,月,日,小时,分钟,秒)
代码(使用Period)看起来像这样:
Map map = activities.stream() .collect(Collectors.toMap(Activity::activityLabel, ac -> new Period(ac.getStartTime(), ac.getEndTime()), (left, right) -> left.plus(right)));
如果您确实要将该Period
输出为String,则需要PeriodFormatter
。
private static PeriodFormatter periodFormatter() { return new PeriodFormatterBuilder() .printZeroAlways() .minimumPrintedDigits(2) .appendYears().appendSeparator("-") .appendMonths().appendSeparator("-") .appendDays().appendLiteral(" ") .appendHours().appendSeparator(":") .appendMinutes().appendSeparator(":") .appendSeconds().toFormatter(); }
然后你的代码看起来会更像这样:
Map map = activities.stream() .collect(Collectors.collectingAndThen( Collectors.toMap( Activity::getLabel, ac -> new Period(ac.getStartTime(), ac.getEndTime()), Period::plus), m -> m.entrySet().stream().collect(Collectors.toMap( Entry::getKey, e -> e.getValue().toString(periodFormatter))))); System.out.println(map); // {Sleeping=00-00-00 15:30:00
正如您在评论中提到的,您确实需要的是DateTime
而不是Period
。
由于DateTime没有DateTime.plus(DateTime)
/ DateTime.minus(DateTime)
api,但你可以在DateTime
上加 / 减一个Period
,那么你需要一个DateTime
来启动,而使用Collectors api的代码正在替换为toMap
使用groupingBy
,在您的情况下执行任务更有效率和表现力 :
DateTime start = DateTime.now(); Map result = list.stream().collect(Collectors.groupingBy( it -> it.activityLabel, Collectors.mapping( it -> new Period(it.startTime, it.endTime), // the important section is here: // 1. merge all of periods by using reducing // 2. convert a Period to a DateTime by collectingAndThen Collectors.collectingAndThen( Collectors.reducing(Period.ZERO, Period::plus), start::plus ) ) ));