Интерфейсы Comparable и Comparator
Существует два способа сравнения объектов:
- С помощью интерфейса
Comparable
. - С помощью интерфейса
Comparator
.
1. Интерфейс Comparable Java
Начнем с интерфейса Comparable
языка Java.
Для того чтобы объекты можно было сравнить и сортировать, они должны реализовать параметризованный интерфейс Comparable
.
Интерфейс Comparable
содержит один единственный метод int compareTo(T item)
, который сравнивает текущий объект с объектом, переданным в качестве параметра.
Если этот метод возвращает отрицательное число, то текущий объект будет располагаться перед тем, который передается через параметр. Если метод вернет положительное число, то, наоборот, после второго объекта. Если метод возвращает ноль, значит, оба объекта равны.
Рассмотрим пример реализации интерфейса Comparable в Java:
public class Person implements Comparable<Person> {
private String firstName;
private String lastName;
private int age;
public Person(String firstName, String lastName, int age) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public int compareTo(Person anotherPerson) {
int anotherPersonAge = anotherPerson.getAge();
return this.age - anotherPersonAge;
}
@Override
public String toString() {
return "Person{" +
"firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
if (getAge() != person.getAge()) return false;
if (getFirstName() != null ? !getFirstName().equals(person.getFirstName()) : person.getFirstName() != null)
return false;
return getLastName() != null ? getLastName().equals(person.getLastName()) : person.getLastName() == null;
}
@Override
public int hashCode() {
int result = getFirstName() != null ? getFirstName().hashCode() : 0;
result = 31 * result + (getLastName() != null ? getLastName().hashCode() : 0);
result = 31 * result + getAge();
return result;
}
}
public class ComparePersonExample {
public static void main(String[] args) {
SortedSet<Person> set = new TreeSet<>();
set.add(new Person("Саша", "Иванов", 36));
set.add(new Person("Маша", "Петрова", 23));
set.add(new Person("Даша", "Сидорова", 34));
set.add(new Person("Вася", "Иванов", 25));
set.forEach(System.out::println);
}
}
2. Интерфейс Comparator
Если класс по какой-то причине не может реализовать интерфейс Comparable
, или же просто нужен другой вариант сравнения, используется интерфейс Comparator
.
Интерфейс содержит метод int compare(T o1, T o2)
, который должен быть реализован классом, реализующим компаратор.
Метод compare
возвращает числовое значение - если оно отрицательное, то объект o1
предшествует объекту o2
, иначе - наоборот. А если метод возвращает ноль, то объекты равны.
Для применения интерфейса нам вначале надо создать класс компаратора, который реализует этот параметризованный интерфейс.
Рассмотрим пример использования интерфейса Comparator:
import java.util.Comparator;
public class PersonComparator implements Comparator<Person> {
@Override
public int compare(Person o1, Person o2) {
return o1.getLastName().compareTo(o2.getLastName());
}
}
import java.util.SortedSet;
import java.util.TreeSet;
public class PersonComparatorExample {
public static void main(String[] args) {
PersonComparator personComparator = new PersonComparator();
SortedSet<Person> set = new TreeSet<>(personComparator);
set.add(new Person("Саша", "Иванов", 36));
set.add(new Person("Маша", "Петрова", 23));
set.add(new Person("Даша", "Сидорова", 34));
set.add(new Person("Вася", "Иванов", 25));
//Обратите внимание - было добавлено 4 элемента, но распечатано 3
set.forEach(System.out::println);
}
}
То же самое перепишем с использованием метода comparing()
интерфейса Comparator
:
import java.util.Comparator;
import java.util.SortedSet;
import java.util.TreeSet;
public class PersonComparingExample {
public static void main(String[] args) {
Comparator<Person> personComparator =
Comparator.comparing(Person::getLastName).thenComparing(Person::getAge);
SortedSet<Person> set = new TreeSet<>(personComparator);
set.add(new Person("Саша", "Иванов", 36));
set.add(new Person("Маша", "Петрова", 23));
set.add(new Person("Даша", "Сидорова", 34));
set.add(new Person("Вася", "Иванов", 25));
set.forEach(System.out::println);
}
}
Зарегистрируйтесь или войдите, чтобы иметь возможность оставить комментарий.