Java でコンパレータをソート

Rashmi Patidar 2023年10月12日
  1. Java で DepartmentComparator を使用して要素を並べ替える
  2. Java 8 の lambda 関数を使用して上記のプログラムを変更する
Java でコンパレータをソート

この記事では、Java のソート・コンパレーターとは何かを定義し、それをプロセスで使用する方法を示します。この概念をよりよく理解するのに役立つ、従うことができるプログラムが含まれています。

Java で DepartmentComparator を使用して要素を並べ替える

ソートは、リスト配列のようなデータ構造を明確な順序で配置するプロセスです。このプロセスは、データ要素を比較することで機能するため、新しい位置を定義します。Java で定義されているソートアルゴリズムには、構造の複雑さに基づいて役立つさまざまなタイプがあります。

以下は、要素をソートするための実装を提供するためにコンパレータインターフェイスをオーバーライドすることを定義するコードブロックです。

import java.util.*;

public class DepartmentComparator {
  public static void main(String[] args) {
    List<Department> departments = Arrays.asList(new Department("dept1", 2001),
        new Department("dept2", 1998), new Department("dept3", 2021));
    Collections.sort(departments, new LexicographicComparator());
    System.out.println("Sorting on the basis of name: " + departments);
    Collections.sort(departments, new YearComparator());
    System.out.println("Sorting on the basis of year: " + departments);
  }

  static class LexicographicComparator implements Comparator<Department> {
    @Override
    public int compare(Department a, Department b) {
      return a.name.compareToIgnoreCase(b.name);
    }
  }

  static class YearComparator implements Comparator<Department> {
    @Override
    public int compare(Department a, Department b) {
      return a.establish_year < b.establish_year ? -1
          : a.establish_year == b.establish_year ? 0
                                                 : 1;
    }
  }

  static class Department {
    String name;
    int establish_year;

    Department(String n, int a) {
      name = n;
      establish_year = a;
    }

    @Override
    public String toString() {
      return String.format("{name=%s, Establish Year=%d}", name, establish_year);
    }
  }
}

上記のプログラムでは、DepartmentComparator クラスは main メソッドを保持し、ドライバーコードとして機能するパブリッククラスです。メインクラス以外に、コードには機能を示すために追加された非公開クラスがあります。Department クラスは、フィールド名と establish_year 変数を保持し、toString() 関数をオーバーライドする POJO です。Bean クラスとは別に、LexicographicComparator クラスと YearComparator クラスは Comparator インターフェイスを実装します。

静的メソッドでは、リストは 3つの要素で初期化されます。Array.asList は、固定サイズの List を返す静的メソッドです。この関数は、クラスのインスタンスを取得してリストに変換します。そのため、department class インスタンスは新しいキーワードを使用して作成され、parameterized コンストラクターと呼ばれるようになりました。このコンストラクターは名前を初期化し、渡されたパラメーターから年を確立します。

リストが作成されると、Collections クラスの sort メソッドが呼び出されます。指定されたコンパレータに基づいて、定義されたリストまたはコレクションをソートします。このメソッドは手動コンパレータを取り、void を返しますが、引数として渡されたコレクションを変更します。要素が異なるタイプの場合、メソッドは ClassCastException をスローします。このメソッドは、最初の引数としてリストコレクションを取り、2 番目の引数として手動コンパレータを取ります。

LexicographicComparator クラスと YearComparator クラスは、手動で比較するために作成されます。クラスは、比較に基づいて int 値を返す単一のメソッド compare を備えた Comparator である機能インターフェイスを実装します。メソッドは、ユーザー指定の実装を定義できるユーザー定義クラスでオーバーライドされます。

LexicographicComparator クラスでは、メソッドは名前に基づいて条件を指定し、渡された引数を比較し、入力が小さいか大きいか等しいかに基づいて -10、または 1 を返します。お互いに。同様に、YearComparator メソッドは、引数として渡された年を比較するためにオーバーライドされます。

以下は、名前、昇順、年ごとに並べられた出力です。

Sorting on the basis of name: [{name=dept1, Establish Year=2001}, {name=dept2, Establish Year=1998}, {name=dept3, Establish Year=2021}]
Sorting on the basis of year: [{name=dept2, Establish Year=1998}, {name=dept1, Establish Year=2001}, {name=dept3, Establish Year=2021}]

Java 8 の lambda 関数を使用して上記のプログラムを変更する

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class DepartmentCompareUsingJava8 {
  public static void main(String[] args) {
    List<DepartmentComparator.Department> departments =
        Arrays.asList(new DepartmentComparator.Department("dept1", 2001),
            new DepartmentComparator.Department("dept2", 1998),
            new DepartmentComparator.Department("dept3", 2021));
    Collections.sort(departments, (a, b) -> a.name.compareToIgnoreCase(b.name));
    System.out.println(departments);
    Collections.sort(departments,
        (a, b)
            -> a.establish_year < b.establish_year ? -1
            : a.establish_year == b.establish_year ? 0
                                                   : 1);
    System.out.println(departments);
  }
}

このプログラムの違いは、Comparator インターフェースを実装する新しいクラスを定義する代わりに、Java 8 関数型インターフェースが毎回新しいクラスでの処理のオーバーヘッドを削減するのに役立つことです。Functional Interface には、実装されていないメソッドまたは abstract メソッドが 1つあります。インターフェイスを実装し、独自のメソッドバージョンを提供するクラスを作成するオーバーヘッドを削減します。

ラムダ ()-> 関数を使用して、メソッドを直接呼び出します。ラムダは関数を引数として扱い、インスタンス化にクラスを必要としません。この関数はパラメーターを受け取り、別のクラスではなく同じ行に実装を提供します。

上記のプログラムの出力は、最初のコードの出力と同じです。

著者: Rashmi Patidar
Rashmi Patidar avatar Rashmi Patidar avatar

Rashmi is a professional Software Developer with hands on over varied tech stack. She has been working on Java, Springboot, Microservices, Typescript, MySQL, Graphql and more. She loves to spread knowledge via her writings. She is keen taking up new things and adopt in her career.

LinkedIn

関連記事 - Java Comparator

関連記事 - Java Sort