如何将参数发送到流中的引用方法(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 ) ) ));