Сравнение объектов и сокращенные варианты

На уроке показали вот такой пример специально опустили private и геттеры и сеттеры:

public class Car implements Comparable<Car> {
    String brand;
    String model;
    int year;

    public Car(String brand, String model, int year) {
        this.brand = brand;
        this.model = model;
        this.year = year;
    }

 @Override
    public int compareTo(Car car) {
        if (this.year == car.year) {
            return 0;
        } else if (this.year < car.year) {
            return -1;
        } else {
            return 1;
        }
    }

Могу ли я заменить вот этот кусок кода:

 @Override
        public int compareTo(Car car) {
            if (this.year == car.year) {
                return 0;
            } else if (this.year < car.year) {
                return -1;
            } else {
                return 1;
            }

На этот:

@Override
    public int compareTo(Car car) {
        return Integer.compare(this.year, car.year);
    }

Подскажите пожалуйста будет ли это правильным или нет?

И еще вопрос по этой же теме:

Вот дополнение кода и сортирует правильно по ГОДУ (year), но как сделать чтобы сортировало по всем полям?

public class Test {
    public static void main(String[] args) {
        TreeSet<Car> myCarList = new TreeSet<>();
        Car firstCar = new Car("Mercedes", "E200", 2015);
        Car secondCar = new Car("Bmw", "M5", 2017);
        Car thirdCar = new Car("Audi", "Q8", 2020);

        myCarList.add(firstCar);
        myCarList.add(secondCar);
        myCarList.add(thirdCar);

        for (Car car: myCarList) {
            System.out.println(car);
        }
    }
}

Чтобы сортировало по всем полям я сделал вот так:

@Override
    public int compareTo(Car car) {
        if (this.brand.equals(car.brand) && this.model.equals(car.model) && this.year == car.year) {
            return 0;
        } else if (this.brand.equals(car.brand) &&  this.model.equals(car.model) && this.year < car.year) {
            return -1;
        } else {
            return 1;
        }
    }

Но сортирует только по году (year), подскажите пожалуйста как сделать в моем примере сортировку по всем полям?


Ответы (1 шт):

Автор решения: First Sin

Ваш вариант абсолютно правильный, так и нужно делать

@Override
public int compareTo(Car car) {
    return Integer.compare(this.year, car.year);
}

Что касается сортировки по нескольким полям, то для этого есть несколько вариантов:

Первый вариант:

Сравнивать каждое поле поэтапно

@Override
public int compareTo(Car car) {
    int result;
    result = brand.compareTo(car.getBrand());
    if(result != 0) return result;
    result = model.compareTo(car.getModel());
    if(result != 0) return result;
    result = Integer.compare(year, car.getYear());
    return result;
}

Второй вариант:

Использовать компаратор. В этом случае в классе нужно создать приватное поле с компаратором, а в методе compareTo вызывать этот компаратор

class Car implements Comparable<Car> {
    private String brand;
    private String model;
    private int year;
    private final Comparator<Car> comparator = Comparator
            .comparing(Car::getBrand)
            .thenComparing(Car::getModel)
            .thenComparingInt(Car::getYear);

    @Override
    public int compareTo(Car car) {
        return comparator.compare(this, car);
    }
    
    // getters, setters, etc...
}

Третий вариант:

Использовать стороннюю библиотеку. Например, вот так это можно сделать с помощью Google Guava

@Override
public int compareTo(Car car) {
    return ComparisonChain.start()
            .compare(brand, car.getBrand())
            .compare(model, car.getModel())
            .compare(year, car.getYear())
            .result();
}
→ Ссылка