Java比较器Arrays.sort() [英] Java Comparator 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屋!