【问题标题】:How to sort a stream by parameter using a comparator in Java 8?如何使用 Java 8 中的比较器按参数对流进行排序?
【发布时间】:2014-09-16 21:46:34
【问题描述】:

如何在 Java 8 中使用比较器和参数对集合进行排序?

这是一段代码:

    List<Point> sortedNeurons = neurons.parallelStream()
        .sorted((n1, n2) -> Double.compare(
            n1.getEuclideanDistanceFrom(inputVector),
            n2.getEuclideanDistanceFrom(inputVector)))
        .collect(Collectors.toList());

您将获得一个参数 inputVector,该参数可以传递给返回原始双精度值的函数。如果应用于集合的元素,它会返回一些数字。 我希望按此值对集合进行排序。 类似的东西:从神经元顺序中选择 id 通过 getEuclideanDistanceFrom(inputVector, id);

这里有三个问题:

  1. nx.getEuclideanDistanceFrom(inputVector) 重复两次。
  2. 当使用 order by 子句时,我想使用 double 类型的自然排序,而不需要声明它,就像在 SQL 查询中一样。
  3. 也许 n1, n2 -> n1, n2 可以用双冒号 :: 表示法代替。

附:我有一种强烈的感觉,可以使用 bifunction 或 biconsumer 之类的东西来修复它......但无法弄清楚......

【问题讨论】:

    标签: java lambda java-8 higher-order-functions java-stream


    【解决方案1】:

    也许你可以用Comparator#comparingDouble

    List<Point> sortedNeurons = neurons.parallelStream()
        .sorted(Comparator.comparingDouble(p -> p.getEuclideanDistanceFrom(inputVector)))
        .collect(Collectors.toList());
    

    【讨论】:

      【解决方案2】:

      这看起来不错。我做得更好:

      List<Point> sortedNeurons = neurons.parallelStream()
          .sorted(Comparator.comparingDouble(inputVector::getEuclideanDistanceFrom))
          .collect(Collectors.toList());
      

      然后我意识到,你可以让它更短:

      List<Point> sortedNeurons =
      neurons.sort(Comparator.comparingDouble(inputVector::getEuclideanDistanceFrom));
      

      显然流不适合排序......

      【讨论】:

      • 不确定您所说的“流不利于对事物进行排序”是什么意思。第一个 sn-p 似乎很合理。如果neurons 是一个列表,则第二个 sn-p 不起作用。 List.sort() 方法对列表进行就地排序并返回 void。
      • 你是对的。这就是我所需要的。从 5 行代码我到了 1!简直不能再好neurons.sort(Comparator.comparingDouble(inputVector::getEuclideanDistanceFrom));
      【解决方案3】:

      我还找到了一种方法来提取可重复使用的比较器:

      public interface Functional<T> {
          public int compareByEuclideanDistance(T o1, T o2);
      }
      
      public class Point implements Functional<Point> {
          @Override
          public int compareByEuclideanDistance(Point o1, Point o2) {
              return Double.compare(this.getEuclideanDistanceFrom(o1),
                  this.getEuclideanDistanceFrom(o2));
          }
      }
      

      现在您可以拨打任何电话,例如:

      neurons.parallelStream()
          .sorted(input::compareByEuclideanDistance)
          .collect(Collectors.toList());
      

      neurons.parallelStream().min(input::compareByEuclideanDistance).get();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-24
        • 2020-07-20
        相关资源
        最近更新 更多