Java8コンパレータ - リストのソート方法を詳しく解説

黄舟
リリース: 2017-03-18 11:11:41
オリジナル
3167 人が閲覧しました

Java8 Comparator - List を並べ替える方法の詳細な説明

この記事では、Java 8 で List を並べ替える方法についていくつかの例を見ていきます。

アルファベット順に並べ替えますStringsLists

List<String> cities = Arrays.asList(
       "Milan",
       "london",
       "San Francisco",
       "Tokyo",
       "New Delhi"
);
System.out.println(cities);
//[Milan, london, San Francisco, Tokyo, New Delhi]
cities.sort(String.CASE_INSENSITIVE_ORDER);
System.out.println(cities);
//[london, Milan, New Delhi, San Francisco, Tokyo]
cities.sort(Comparator.naturalOrder());
System.out.println(cities);
//[Milan, New Delhi, San Francisco, Tokyo, london]
ログイン後にコピー

London の「L」は、Comparator.naturalOrder() (最初に大文字を並べ替えるコンパレータを返します) と String.CASE_INSENSITIVE_ORDER (大文字と小文字を区別しないコンパレータを返します) をより強調表示するために小文字になっています。

基本的に、Java 7 には List を受け入れ、最後に Comparator を受け入れる Collection.sort() があります。Java 8 には、Comparator を受け入れる新しい List.sort() があります。

整数でリストを並べ替え
List<Integer> numbers = Arrays.asList(6, 2, 1, 4, 9);
System.out.println(numbers); //[6, 2, 1, 4, 9]
numbers.sort(Comparator.naturalOrder());
System.out.println(numbers); //[1, 2, 4, 6, 9]
ログイン後にコピー

文字列フィールドでリストを並べ替え

Movie クラスがあり、リストを「タイトル title で」並べ替えたいとします。 Comparator.comparing() を使用して、

関数を渡します。この関数は、この場合、タイトルの並べ替えに使用されるフィールドを抽出します。

List<Movie> movies = Arrays.asList(
        new Movie("Lord of the rings"),
        new Movie("Back to the future"),
        new Movie("Carlito&#39;s way"),
        new Movie("Pulp fiction"));
movies.sort(Comparator.comparing(Movie::getTitle));
movies.forEach(System.out::println);
ログイン後にコピー

出力:

Movie{title=&#39;Back to the future&#39;}
Movie{title=&#39;Carlito&#39;s way&#39;}
Movie{title=&#39;Lord of the rings&#39;}
Movie{title=&#39;Pulp fiction&#39;}
ログイン後にコピー

コンパレーターを渡していないことに気づくかもしれませんが、リストは正しくソートされています。これは、抽出されたフィールドであるタイトルが文字列であり、文字列が Comparable

インターフェース を実装しているためです。 Comparator.comparing() 実装を見ると、抽出されたキーに対して CompareTo を呼び出していることがわかります。

return (Comparator<T> & Serializable)
            (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
ログイン後にコピー

double フィールドでリストを並べ替える

同様の方法で、Comparator.comparingDouble() を使用して double 値を比較できます。この例では、映画のリストを最高評価から最低評価の順に並べたいと考えています。

List<Movie> movies = Arrays.asList(
        new Movie("Lord of the rings", 8.8),
        new Movie("Back to the future", 8.5),
        new Movie("Carlito&#39;s way", 7.9),
        new Movie("Pulp fiction", 8.9));
movies.sort(Comparator.comparingDouble(Movie::getRating)
                      .reversed());
movies.forEach(System.out::println);
ログイン後にコピー

デフォルトの自然な順序を最低から最高まで逆にするために、コンパレータで reversed 関数を使用します。 Comparator.comparingDouble() は内部で Double.compare() を使用します。

int または long を比較する必要がある場合は、それぞれ CompareInt() と CompareLong() を使用できます。

カスタム コンパレータを使用してリストを並べ替える

前の例では、必要がなかったためコンパレータを指定しませんでしたが、独自のコンパレータを定義した例を見てみましょう。 Movie クラスには、3 番目の

constructor パラメータを使用して設定される新しいフィールド「stared」があります。この例では、スター付き映画がリストの先頭になるようにリストを並べ替えます。

List<Movie> movies = Arrays.asList(
        new Movie("Lord of the rings", 8.8, true),
        new Movie("Back to the future", 8.5, false),
        new Movie("Carlito&#39;s way", 7.9, true),
        new Movie("Pulp fiction", 8.9, false));
movies.sort(new Comparator<Movie>() {
    @Override
    public int compare(Movie m1, Movie m2) {
        if(m1.getStarred() == m2.getStarred()){
            return 0;
        }
        return m1.getStarred() ? -1 : 1;
     }
});
movies.forEach(System.out::println);
ログイン後にコピー

結果は次のようになります:

Movie{starred=true, title=&#39;Lord of the rings&#39;, rating=8.8}
Movie{starred=true, title=&#39;Carlito&#39;s way&#39;, rating=7.9}
Movie{starred=false, title=&#39;Back to the future&#39;, rating=8.5}
Movie{starred=false, title=&#39;Pulp fiction&#39;, rating=8.9}
ログイン後にコピー

もちろん、次のように匿名クラスの代わりに lambda

expression を使用することもできます:

movies.sort((m1, m2) -> {
    if(m1.getStarred() == m2.getStarred()){
        return 0;
    }
    return m1.getStarred() ? -1 : 1;
});
ログイン後にコピー

Comparator.comparing() を再度使用することもできます:

movies.sort(Comparator.comparing(Movie::getStarred, (star1, star2) -> {
    if(star1 == star2){
         return 0;
    }
    return star1 ? -1 : 1;
}));
ログイン後にコピー

最新の例では、 Comparator.comparing() は、ソートに使用されるキーを抽出する関数として最初の引数を取り、2 番目の引数として Comparator を受け取ります。 Comparator は抽出されたキーを比較に使用します。star1 と star2 は実際にはブール値で、それぞれ m1.getStarred() と m2.getStarred() を表します。

比較チェーンを使用してリストを並べ替える

この最後の例では、スター付き映画を先頭に追加し、評価順に並べ替えます。

List<Movie> movies = Arrays.asList(
        new Movie("Lord of the rings", 8.8, true),
        new Movie("Back to the future", 8.5, false),
        new Movie("Carlito&#39;s way", 7.9, true),
        new Movie("Pulp fiction", 8.9, false));
movies.sort(Comparator.comparing(Movie::getStarred)
                      .reversed()
                      .thenComparing(Comparator.comparing(Movie::getRating)
                      .reversed())
);
movies.forEach(System.out::println);
ログイン後にコピー

出力は次のとおりです:

Movie{starred=true, title=&#39;Lord of the rings&#39;, rating=8.8}
Movie{starred=true, title=&#39;Carlito&#39;s way&#39;, rating=7.9}
Movie{starred=false, title=&#39;Pulp fiction&#39;, rating=8.9}
Movie{starred=false, title=&#39;Back to the future&#39;, rating=8.5}
ログイン後にコピー
ご覧のとおり、最初に星で並べ替え、次に評価で並べ替えます。最高の値と真の 1 位を求めるため、両方とも逆になります。

以上がJava8コンパレータ - リストのソート方法を詳しく解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート