Пример сортировки Java-объектов (Comparable и Comparator)

Пример сортировки объектов Java (Comparable и Comparator)

В этом руководстве показано использованиеjava.lang.Comparable иjava.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's «FruitName» или «Количество»? Интерфейс 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 содержит статический методFruitNameComparator для сравнения «fruitName». Теперь объект Fruit может сортироваться по свойству «количество» или «fruitName». Запустите это снова.

1. Сортировать массив Fruit по его свойству «fruitName» в порядке возрастания.

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. Сортировать массив Fruit по его количественному свойству в порядке возрастания.

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.Comparable иjava.util.Comparator очень эффективны, но требуется время, чтобы понять и использовать их, возможно, это из-за отсутствия подробного примера.

Мои мысли…

В будущем класс Arrays должен предоставлять более общий и удобный метод -Arrays.sort(Object, String, flag).

Сортировать массив объектов по его «fruitName» в порядке возрастания.

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

Сортировать массив объектов по его «количеству» в порядке возрастания.

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