【问题标题】:Calculate Median using Java Stream API [duplicate]使用Java Stream API计算中位数[重复]
【发布时间】:2020-05-09 18:58:39
【问题描述】:

是否可以使用 Java Stream API 来查找数值集合的中位数?我有一个未排序的List<Double> 类型的变量。

从 JDK9 到 14 的 javadocs 似乎表明 median() 不是 DoubleStream 的有效方法。 不过,Average、Minimum、Maximum、Count 和 Sum 都是有效的聚合函数。

median() 是不是一个有效的方法,因为它在流式传输之前需要一个排序的集合?

这适用于average()

   // Function to find average element from a List of Integers in Java 9 and above
   public static Double getAverageWithStream(List<Double> list) {
      OptionalDouble average = list.stream() // Stream<Double>
                                 .mapToDouble(v -> v) // DoubleStream
                                 .average(); // OptionalDouble

      // Print out a message about the 'average' variable's value
      // Note: ifPresentOrElse() was introduced in JDK9
      average.ifPresentOrElse(
         // message the value if one exists
         (value) -> {
            System.out.println("The average value is " + value);
         },
         // Alert the user that there is no value
         () -> {
            System.out.println("No average could be determined!");
         }
      ); // end ifPresentOrElse()

      return average.orElse(Double.NaN);
   } // end getAverageWithStream()

【问题讨论】:

    标签: java


    【解决方案1】:

    没有中间值(),您必须自己滚动,但我认为考虑到它的性质,需要进行排序。

    如果您使用中位数(而不是均值)的数学定义,那么您只需要找到排序列表的中间部分:

    mylist.sort()
    int median = mylist[list.size/2]
    

    但是您需要将您的信息流变成一个列表来执行此操作,这可能不是您想要的。

    【讨论】:

      【解决方案2】:

      根据@Robert Bain 留下的评论,我的方法需要按以下方式更改以支持中值聚合:

         /**
          * Function to find median element from a List of Integers in Java 9 and above
          * @param list List<Double>
          * @return Double
          */
         public static Double getMedianWithStream(List<Double> list) {
            DoubleStream sortedNumbers = list.stream() // Stream<Double>
                                       .mapToDouble(v -> v) // DoubleStream
                                       .sorted(); // DoubleStream sorted
      
            OptionalDouble median = (
               list.size() % 2 == 0 ?
               sortedNumbers.skip((list.size() / 2) - 1)
                           .limit(2)
                           .average() :
               sortedNumbers.skip(list.size() / 2)
                           .findFirst()
            );
      
            // Print out a message about the 'average' variable's value
            // Note: ifPresentOrElse() was introduced in JDK9
            median.ifPresentOrElse(
               // message the value if one exists
               (value) -> {
                  System.out.println("The median value is " + value);
               },
               // Alert the user that there is no value
               () -> {
                  System.out.println("No median could be determined!");
               }
            ); // end ifPresentOrElse()
      
            return median.orElse(Double.NaN);
         } // end getAverageWithStream()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-07-24
        • 1970-01-01
        • 2019-04-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多