Java比较器Arrays.sort() [英] Java Comparator Arrays.sort()

查看:756
本文介绍了Java比较器Arrays.sort()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想根据一些规则对Java中的二维数组的数组进行排序,比方说到原点的距离。我看到了使用 Arrays.sort()的几种方法:

I want to sort an array of 2 dimensional arrays in Java according to some rules, let's say the distance from the origin. I saw several ways of doing it using Arrays.sort():

1) Arrays.sort(points,Comparator.comparing(p-> p [0] * p [0] + p [1] * p [1]));

2) Arrays.sort(points,(p1,p2)-> p1 [0] * p1 [0] + p1 [1] * p1 [1]- p2 [0] * p2 [0]-p2 [1] * p2 [1]);

3)定义 class

class Point implements Comparable<Point>{
     // class variables, constructor
     public int compareTo(Point p) {
         return (x*x + y*y).compareTo(p.x*p.x + p.y*p.y);
     }
}

数组 pts Points 的code>,并使用 Arrays.sort(pts)。我的问题是关于 1) 2):我看到了之间的区别,但我不知道何时使用一个和何时使用另一个,以及确切的 Comparator.comparing()正在执行。为什么第一个解决方案仅携带一个点来承载信息,而第二个解决方案则需要两个点?

An array pts of type Points is then created and Arrays.sort(pts) is used. My question is regarding 1) and 2): I see the difference between the but I do not understand when to use one and when to use the other and what exactly Comparator.comparing() is doing. Why is the first solution carrying the information just with one point while the second need two points?

推荐答案

Comparator.comparing 的实现如下:

public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
        Function<? super T, ? extends U> keyExtractor)
{
    Objects.requireNonNull(keyExtractor);
    return (Comparator<T> & Serializable)
        (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
}

即它使用传递给它的 Function ,以便将每个比较的元素转换为 Comparable ,然后使用可比较 compareTo 方法。

i.e. it uses the Function you pass to it in order to transform each of the compared elements into a Comparable, and then uses the Comparable's compareTo method.

正在传递函数 p-> p [0] * p [0] + p [1] * p [1] ,将每个点转换为其平方和。然后,当 Comparator 需要比较两个点时,它会比较两个点的平方和,这几乎等同于计算两个点的平方和之差。两点(这并不完全相等,因为通过计算它们的差来比较两个数字可能会在数值溢出的情况下产生错误的输出)。

When you are passing the function p -> p[0]*p[0] + p[1]*p[1], you are converting each point to its sum of squares. Then, when the Comparator needs to compare two points, it compares the sum of squares of the two points, which is almost equivalent to computing the difference of the sums of squares of the two points (it's not exactly equivalent, since comparing two numbers by computing their difference can produce wrong output in case of numeric overflow).

这正是您第二个比较器-(p1,p2)-> p1 [0] * p1 [0] + p1 [1] * p1 [1]-p2 [0] * p2 [0]-p2 [1] * p2 [1] -确实,

That's exactly what your second Comparator - (p1, p2) -> p1[0]*p1[0] + p1[1]*p1[1] - p2[0]*p2[0] - p2[1]*p2[1] - does,

p1 [0] * p1 [0] + p1 [1] * p1 [1]-p2 [0] * p2 [0] -p2 [1] * p2 [1] ==
(p1 [0] * p1 [0] + p1 [1] * p1 [1])-(p2 [0] * p2 [0] + p2 [1] * p2 [1])

使用 Comparator.comparing()比较安全,因为它比较两个点的平方和而不计算其差。它使用 Double compareTo()代替(假设点的坐标为 Double double )。

Using Comparator.comparing() is safer, since it compares the sums of squares of the two points without computing their difference. It uses Double's compareTo() instead (assuming the coordinates of your points are Double or double).

换句话说,第一种选择使用函数只需要一点,因为此函数告诉 Comprator.comparing 如何转换这两个点。

In other words, the first alternative uses a Function that needs just one point since this function tells Comprator.comparing how to transform each of the 2 points.

另一方面,第二个选择接受2点(这是 Comparator.compare()方法的必需参数)并确定这两个点的相对顺序。

On the other hand, the second alternative accepts 2 points (which are the required arguments of the Comparator.compare() method) and determines the relative order of these 2 points.

这篇关于Java比较器Arrays.sort()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆