Porównujemy obiekty - interfejs Comparable<T>

Często chcemy porównać ze sobą dwa obiekty jakiejś klasy. Oczywiście możemy porównać odpowiednie pola klasy i zwrócić wynik, ale.... rozwiązanie idealne polega na zaimplementowaniu w naszej klasie interfejsu Comparable<T>. Dzięki implementacji interfejsu, obiekty powstałe na bazie naszej klasy będą mogły być porównywane ze sobą. Taki sposób porównywania (mówiąc inaczej uporządkowania obiektów) jest wykorzystywany przez Javę np. w kolekcjach. Standardowe klasy np. klasa String również implementują ten interfejs. Dzięki temu porównując dwa łańcuchy tekstowe wiemy który jest "mniejszy", a który "większy" (w tym przypadku wykorzystywane jest uporządkowanie alfabetyczne). Wróćmy do interfejsu Comparable<T>, ma on tylko jedną metodę:

public int compareTo(T obiekt);
Metoda compareTo() może zwracać wartość ujemną, dodatnią albo zero odpowiednio dla obiektów mniejszych, większych lub równych obiektowi przekazanemu jako parametr jej wywołania. Wykorzystajmy interfejs Comparable<T> w przykładowej klasie Student. Nasza klasa będzie posiadać trzy pola: imię, nazwisko oraz numer albumu. Chcemy aby obiekty tworzone na jej podstawie można było porównywać ze sobą według nazwiska. Zastosowanie typów generycznych w interfejsie umożliwia nam swobodniejszy dostęp do obiektów, nie musimy wykonywać rzutowania (więcej o typach generycznych - Typy generyczne).

/**
* Klasa Student
* Przykład wykorzystania interfejsu Comparable<T>
* @author kodatnik.blogspot.com
*/

// klasa Student implementuje interfejs Comparable<T>
// czyli musi mieć wszystkie metody związane z tym interfejsem
class Student implements Comparable<Student> {
 // pola prywatne
 private String imie;
 private String nazwisko;
 private int nrAlbumu;

 // konstruktor klasy
 public Student(String imie, String nazwisko, int nrAlbumu) {
  this.imie = imie;
  this.nazwisko = nazwisko;
  this.nrAlbumu = nrAlbumu;
 }

 // metoda wymagana przez interfejs Comparable<T>
 public int compareTo(Student obiekt) {
  // zwracamy wynik porównania dwóch pól nazwisko
  // (korzystamy z porównania dostępnego w klasie String)
  return nazwisko.compareTo(obiekt.nazwisko);
 }

 // metoda przesłonięta, zwraca nam tekstową reprezentację obiektu
 public String toString() {
  return (nazwisko + " " + imie + " " + nrAlbumu);
 }
}
Poniżej przykład wykorzystania klasy Student. Tworzymy tablicę obiektów, sortujemy ją i wyświetlamy na ekranie.

/**
* Klasa TestPorownania
* Przykład wykorzystania klasy implementującej interfejs Comparable<T>
* @author kodatnik.blogspot.com
*/

// wykorzystujemy klasę Arrays (obsługa tablic)
import java.util.Arrays;

public class TestPorownania {
 public static void main(String[] args) {
  // tworzymy tablicę studentów o rozmiarze 6
  Student[] studenci = new Student[6];

  // wypełniamy poszczególne elementy tablicy obiektami typu Student
  studenci[0] = new Student("Marek", "Zielony", 4325);
  studenci[1] = new Student("Jacek", "Mruczek", 7453);
  studenci[2] = new Student("Iwona", "Lonkis", 2644);
  studenci[3] = new Student("Marta", "Annas", 1632);
  studenci[4] = new Student("Adam", "Mruczek", 3856);
  studenci[5] = new Student("Marek", "Zielony", 4287);

  // sortujemy tablicę za pomocą metody sort dostępnej w klasie Arrays
  // elementy tablicy zostaną posortowane według metody compareTo()
  Arrays.sort(studenci);

  // wyświetlamy zawartość posortowanej tablicy
  for (Student st: studenci){
   System.out.println(st);
  }
 }
}
Uruchomiona aplikacja:
Annas Marta 1632
Lonkis Iwona 2644
Mruczek Jacek 7453
Mruczek Adam 3856
Zielony Marek 4325
Zielony Marek 4287
Możemy poszerzyć zakres porównania dla studentów o takich samych nazwiskach. W ich przypadku będziemy porównywać również imiona, a gdy one również będą takie same numery albumu. Poprawiona metoda compareTo() przedstawia się następująco:

public int compareTo(Student obiekt) {
 // jeżeli nazwiska są takie same
 if (nazwisko.compareTo(obiekt.nazwisko) == 0)
  // sprawdzamy imiona
  if(imie.compareTo(obiekt.imie) == 0)
   // jeśli są takie same zwracamy różnicę z numerów albumu (dla takich samych będzie to zero)
   return nrAlbumu - obiekt.nrAlbumu;
  else
   // w przeciwnym wypadku zwracamy porównanie imion
   return imie.compareTo(obiekt.imie);
 else
  // w przeciwnym wypadku zwracamy porównanie nazwisk
  return nazwisko.compareTo(obiekt.nazwisko);
}
Wynik działania ze zmienioną metodą compareTo():
Annas Marta 1632
Lonkis Iwona 2644
Mruczek Adam 3856
Mruczek Jacek 7453
Zielony Marek 4287
Zielony Marek 4325


6 Komentarzy - Porównujemy obiekty - interfejs Comparable<T>

Interfejs pisze...

Bardzo Ciekawy artykuł na temat
Interfejs, można się ciekawych rzeczy dowiedzieć ;D

Anonimowy pisze...

Dzięki za wrzutkę

Anonimowy pisze...

Skoro nazwisko ma zasięg private to dlaczego możemy odwołaś się do niego w metodzie compareTo poprzez obiekt.nazwisko?

Anonimowy pisze...

Bo private odnosi się do klas, a nie do obiektów, obiekt jest klasy Student, a compareTo jest też w klasie Student, więc widać wszystkie jego składowe.

ka a pisze...

Student st: studenci" co oznacza ??

Anonimowy pisze...

import java.util.Comparator;


public class ComparatorPart implements Comparator{

@Override
public int compare(Part o1, Part o2) {
int ilosc = o1.getQuantity() - o2.getQuantity();
if(ilosc == 0) {
return o1.compareTo(o2);
}
return ilosc;

}

}

Prześlij komentarz

Możesz użyć niektórych tagów HTML, takich jak <b>, <i>, <u>, <a> Nie spamuj :)

Popularne posty