Javaオブジェクトのソートの例(ComparableとComparator)

Javaオブジェクトのソートの例(比較可能およびコンパレーター)

このチュートリアルでは、java.lang.Comparablejava.util.Comparatorを使用して、プロパティ値に基づいてJavaオブジェクトをソートする方法を示します。

1. 配列を並べ替える

配列をソートするには、Arrays.sort()を使用します。

    String[] fruits = new String[] {"Pineapple","Apple", "Orange", "Banana"};

    Arrays.sort(fruits);

    int i=0;
    for(String temp: fruits){
        System.out.println("fruits " + ++i + " : " + temp);
    }

出力

fruits 1 : Apple
fruits 2 : Banana
fruits 3 : Orange
fruits 4 : Pineapple

2. ArrayListを並べ替える

ArrayListをソートするには、Collections.sort()を使用します。

    List fruits = new ArrayList();

    fruits.add("Pineapple");
    fruits.add("Apple");
    fruits.add("Orange");
    fruits.add("Banana");

    Collections.sort(fruits);

    int i=0;
    for(String temp: fruits){
        System.out.println("fruits " + ++i + " : " + temp);
    }

出力

fruits 1 : Apple
fruits 2 : Banana
fruits 3 : Orange
fruits 4 : Pineapple

3. 比較可能なオブジェクトを並べ替える

Javaオブジェクトはどうですか? Fruitクラスを作成しましょう:

public class Fruit{

    private String fruitName;
    private String fruitDesc;
    private int quantity;

    public Fruit(String fruitName, String fruitDesc, int quantity) {
        super();
        this.fruitName = fruitName;
        this.fruitDesc = fruitDesc;
        this.quantity = quantity;
    }

    public String getFruitName() {
        return fruitName;
    }
    public void setFruitName(String fruitName) {
        this.fruitName = fruitName;
    }
    public String getFruitDesc() {
        return fruitDesc;
    }
    public void setFruitDesc(String fruitDesc) {
        this.fruitDesc = fruitDesc;
    }
    public int getQuantity() {
        return quantity;
    }
    public void setQuantity(int quantity) {
        this.quantity = quantity;
    }
}

並べ替えるには、Arrays.sort()をもう一度考えてみてください。以下の例を参照してください。

package com.example.common.action;

import java.util.Arrays;

public class SortFruitObject{

    public static void main(String args[]){

        Fruit[] fruits = new Fruit[4];

        Fruit pineappale = new Fruit("Pineapple", "Pineapple description",70);
        Fruit apple = new Fruit("Apple", "Apple description",100);
        Fruit orange = new Fruit("Orange", "Orange description",80);
        Fruit banana = new Fruit("Banana", "Banana description",90);

        fruits[0]=pineappale;
        fruits[1]=apple;
        fruits[2]=orange;
        fruits[3]=banana;

        Arrays.sort(fruits);

        int i=0;
        for(Fruit temp: fruits){
           System.out.println("fruits " + ++i + " : " + temp.getFruitName() +
            ", Quantity : " + temp.getQuantity());
        }

    }
}

良い試みですが、Arrays.sort()が何をすることを期待しますか? Fruitクラスで何をソートするかについても言及しませんでした。 そのため、次のエラーが発生します。

Exception in thread "main" java.lang.ClassCastException:
com.example.common.Fruit cannot be cast to java.lang.Comparable
    at java.util.Arrays.mergeSort(Unknown Source)
    at java.util.Arrays.sort(Unknown Source)

オブジェクトをそのプロパティで並べ替えるには、オブジェクトにComparableインターフェイスを実装させ、compareTo()メソッドをオーバーライドする必要があります。 新しいFruitクラスをもう一度見てみましょう。

public class Fruit implements Comparable{

    private String fruitName;
    private String fruitDesc;
    private int quantity;

    public Fruit(String fruitName, String fruitDesc, int quantity) {
        super();
        this.fruitName = fruitName;
        this.fruitDesc = fruitDesc;
        this.quantity = quantity;
    }

    public String getFruitName() {
        return fruitName;
    }
    public void setFruitName(String fruitName) {
        this.fruitName = fruitName;
    }
    public String getFruitDesc() {
        return fruitDesc;
    }
    public void setFruitDesc(String fruitDesc) {
        this.fruitDesc = fruitDesc;
    }
    public int getQuantity() {
        return quantity;
    }
    public void setQuantity(int quantity) {
        this.quantity = quantity;
    }

    public int compareTo(Fruit compareFruit) {

        int compareQuantity = ((Fruit) compareFruit).getQuantity();

        //ascending order
        return this.quantity - compareQuantity;

        //descending order
        //return compareQuantity - this.quantity;

    }
}

新しいFruitクラスは、Comparableインターフェイスを実装し、compareTo()メソッドをオーバーライドして、その数量プロパティを昇順で比較しました。

compareTo()メソッドは説明が難しく、整数ソートでは覚えておいてください。

  1. this.quantity – compareQuantity is ascending order.

  2. compareQuantity – this.quantityは降順です。

compareTo()メソッドの詳細については、このComparable documentationをお読みください。

もう一度実行します。これで、Fruits配列はその量によって昇順で並べ替えられます。

fruits 1 : Pineapple, Quantity : 70
fruits 2 : Orange, Quantity : 80
fruits 3 : Banana, Quantity : 90
fruits 4 : Apple, Quantity : 100

4. コンパレータでオブジェクトを並べ替える

Fruitの「fruitName」または「Quantity」で並べ替えるのはどうですか? Comparableインターフェイスでは、単一のプロパティのみをソートできます。 複数のプロパティで並べ替えるには、Comparatorが必要です。 更新された新しいFruitクラスをもう一度参照してください。

import java.util.Comparator;

public class Fruit implements Comparable{

    private String fruitName;
    private String fruitDesc;
    private int quantity;

    public Fruit(String fruitName, String fruitDesc, int quantity) {
        super();
        this.fruitName = fruitName;
        this.fruitDesc = fruitDesc;
        this.quantity = quantity;
    }

    public String getFruitName() {
        return fruitName;
    }
    public void setFruitName(String fruitName) {
        this.fruitName = fruitName;
    }
    public String getFruitDesc() {
        return fruitDesc;
    }
    public void setFruitDesc(String fruitDesc) {
        this.fruitDesc = fruitDesc;
    }
    public int getQuantity() {
        return quantity;
    }
    public void setQuantity(int quantity) {
        this.quantity = quantity;
    }

    public int compareTo(Fruit compareFruit) {

        int compareQuantity = ((Fruit) compareFruit).getQuantity();

        //ascending order
        return this.quantity - compareQuantity;

        //descending order
        //return compareQuantity - this.quantity;

    }

    public static Comparator FruitNameComparator
                          = new Comparator() {

        public int compare(Fruit fruit1, Fruit fruit2) {

          String fruitName1 = fruit1.getFruitName().toUpperCase();
          String fruitName2 = fruit2.getFruitName().toUpperCase();

          //ascending order
          return fruitName1.compareTo(fruitName2);

          //descending order
          //return fruitName2.compareTo(fruitName1);
        }

    };
}

Fruitクラスには、「fruitName」を比較するための静的なFruitNameComparatorメソッドが含まれています。 これで、Fruitオブジェクトは、「quantity」または「fruitName」プロパティのいずれかでソートできます。 もう一度実行してください。

1. 「fruitName」プロパティに基づいて昇順でFruit配列をソートします。

Arrays.sort(fruits, Fruit.FruitNameComparator);

出力

fruits 1 : Apple, Quantity : 100
fruits 2 : Banana, Quantity : 90
fruits 3 : Orange, Quantity : 80
fruits 4 : Pineapple, Quantity : 70

2. 「数量」プロパティに基づいて、フルーツ配列を昇順で並べ替えます。

Arrays.sort(fruits)

出力

fruits 1 : Pineapple, Quantity : 70
fruits 2 : Orange, Quantity : 80
fruits 3 : Banana, Quantity : 90
fruits 4 : Apple, Quantity : 100

java.lang.Comparablejava.util.Comparatorは強力ですが、詳細な例が不足しているためか、理解して利用するには時間がかかります。

私の考え…

将来的には、Arraysクラスはより一般的で便利なメソッドArrays.sort(Object, String, flag)を提供するはずです。

オブジェクト配列を「fruitName」で昇順に並べ替えます。

Arrays.sort(fruits, fruitName, Arrays.ASCENDING);

オブジェクト配列を「量」で昇順に並べ替えます。

Arrays.sort(fruits, quantity, Arrays.DESCENDING);