私は、ソートしたいarray
のは、原点からの距離を言わせて、いくつかのルールに従って、Javaで2次元配列のを。私が使用してそれを行うにはいくつかの方法を見ました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
、その後に作成され、Arrays.sort(pts)
使用されています。私の質問はに関するされ1)及び2) :私は違いを見たが1のとき、他のと正確に何を使用するために使用するとき、私は理解していないComparator.comparing()
やっているし。なぜ第必要ながら一点でちょうど2つの点を情報を搬送する第1の解決策はありますか?
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
、その後、使用Comparable
のcompareTo
方法を。
あなたが機能を渡しているときp -> p[0]*p[0] + p[1]*p[1]
、あなたは正方形のその合計に各ポイントを変換しています。ときに、Comparator
ニーズが2点を比較するために、それは計算することによって、2つの数値を比較するため、(それが全く同じではない2点の二乗の和の差を計算することとほぼ等価である2点の二乗和は、比較しますそれらの差)は数値のオーバーフローの場合、間違った出力を生成することができます。
それはまさにあなたの秒だComparator
- (p1, p2) -> 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] == (p1[0]*p1[0] + p1[1]*p1[1]) - (p2[0]*p2[0] + p2[1]*p2[1])
。
使用はComparator.comparing()
、それが彼らの差を計算することなく、2つの点の二乗和を比較するため、安全です。これは、使用していますDouble
「S compareTo()
(あなたの点の座標であると仮定代わりに、Double
またはdouble
)。
換言すれば、第1の代替が使用しFunction
、この関数が伝えためだけの一点を必要とすることComprator.comparing
2点のそれぞれを変換する方法。
一方、第二の代替法は、(必要な引数で2点受け入れるComparator.compare()
法)と、これらの2点の相対的な順序を決定します。