从日期列表中获取平均值

时间:2017-05-19 13:38:15

标签: java java-8

我有一个Date对象列表,想要从这个列表中获取平均值。使用lambda表达式有一种简单的方法吗?

例如,如果我的列表包含两个日期:

01/01/2017

31/01/2017

结果将是:

15/01/2017

解决方案

Date averaging = Stream.of(date("2017-01-01"), date("2017-01-31"))
            .map(Date::getTime)
            .collect(Collectors.collectingAndThen(
                    Collectors.averagingLong(Long::longValue),
                    it -> new Date(
                            (it.longValue() - TimeUnit.DAYS.toMillis(1))
                                    / TimeUnit.SECONDS.toMillis(1)
                                    * TimeUnit.SECONDS.toMillis(1)
                    )
            ));

2 个答案:

答案 0 :(得分:1)

假设您的日期在列表中,并且java8是一个选项:

long ave = (long) myList.stream().mapToLong(Date::getTime).average().getAsDouble();
System.out.println(new Date(ave));

使用Java Time API

List<LocalDate> myList = new ArrayList<>();
myList.add(LocalDate.of(2017, 01, 01));
myList.add(LocalDate.of(2017, 01, 31));
myList.forEach(System.out::println);

long ave = (long) myList.stream()
            .mapToLong(x -> x.atStartOfDay(ZoneId.systemDefault()).toInstant().toEpochMilli()).average()
            .getAsDouble();
System.out.println(new Date(ave));

输出:

  

2017年1月16日星期一00:00:00 CET

答案 1 :(得分:0)

如果您在日期类型中执行getTime(),则自1970年1月1日,格林威治标准时间00:00:00起,以毫秒为单位,为您的每个日期执行此操作,添加所有毫秒并除以数组的长度。然后带上你的号码(例如现在为1495201767023)并创建一个新的日期。 Date date = new Date(1495201767023L)(不要忘记L)它应该有效

正如评论中所说,处理这样的Long可能会导致溢出。因此,尝试除以常数或平均递增