Baza Wiedzy

Metoda equals()

Metoda equals() służy w Javie do porównywania typów obiektowych. W odróżnieniu od typów prostych operator == w przypadku typów obiektowych porównuje referencje, a nie równość strukturalną obiektów, z tego powodu porównanie dwóch obiektów poprzez:

obiekt1 == obiekt2

Kurs Programowania Java

w większości przypadków jest nieskuteczne i otrzymujemy wynik, którego nie oczekiwaliśmy.

    • Generowanie metody equals

      Metoda equals() a klasa Object

      Metoda equals() zdefiniowana jest w klasie Object, a ponieważ jest to klasa, po której dziedziczą wszystkie klasy Javy, to możemy ją wywołać na dowolnym obiekcie. Domyślna implementacja metody equals() sprowadza się jednak jedynie do porównania referencji ==, czyli w większości przypadków nie jest zbyt użyteczna. W klasach, których obiekty będziemy ze sobą porównywali powinniśmy ją nadpisać.

      Przykład wykorzystania

      Załóżmy, że w naszym projekcie istnieje klasa Product przechowująca informacje o nazwie i cenie produktu.

      public class Product {
          private String name;
          private double price;
          public Product(String name, double price) {
              this.name = name;
              this.price = price;
          }
          public String getName() {
              return name;
          }
          public void setName(String name) {
              this.name = name;
          }
          public double getPrice() {
              return price;
          }
          public void setPrice(double price) {
              this.price = price;
          }
      }
      

      Jeżeli utworzymy dwa obiekty przechowujące identyczną nazwę oraz cenę i spróbujemy je porównać za pomocą operatora == lub metody equals() odziedziczonej z klasy Object, to w wyniku dwa razy otrzymamy false. Dzieje się tak dlatego, że dwie referencje wskazujące na dwa różne obiekty nie są sobie równe.

      public class Shop {
          public static void main(String[] args) {
              Product product1 = new Product("Milk", 2.5);
              Product product2 = new Product("Milk", 2.5);
              System.out.println(product1 == product2); //false
              System.out.println(product1.equals(product2)); //false
          }
      }
      

      compare

      Kurs Programowania Java

      Zazwyczaj przy porównywaniu obiektów będziemy chcieli jednak sprawdzić ich równość strukturalną (czy przechowują te same informacje) i w tym celu należy nadpisać metodę equals.

      public class Product {
          private String name;
          private double price;
      //gettery settery, konstruktor
      
          @Override
          public boolean equals(Object obj) {
              if (this == obj)
                  return true;
              if (obj == null)
                  return false;
              if (getClass() != obj.getClass())
                  return false;
              Product other = (Product) obj;
              if (name == null) {
                  if (other.name != null)
                      return false;
              } else if (!name.equals(other.name))
                  return false;
              if (Double.doubleToLongBits(price) != Double.doubleToLongBits(other.price))
                  return false;
              return true;
          }
      }
      

      W metodzie equals powinniśmy:

        • porównać wartość referencji

        • sprawdzić, czy przekazany jako argument obiekt nie jest wartością null

        • sprawdzić, czy przekazany obiekt jest tego samego typu co obiekt, w na którym operujemy, a jeśli tak to dokonać rzutowania

        • porównać poszczególne pola obiektu zwracając uwagę na to, czy nie są one wartościami null i a jeśli są typami obiektowymi, to porównywać je także poprzez metode equals, a nie ==

        Taki schemat postępowania sprawi, że metoda equals będzie wydajna, np. porównanie product1.equals(product1) zwróci true już na pierwszym warunku więc reszta nie będzie sprawdzana.

        public class Shop {
            public static void main(String[] args) {
                Product product1 = new Product("Milk", 2.5);
                Product product2 = new Product("Milk", 2.5);
                System.out.println(product1 == product2); //false
                System.out.println(product1.equals(product2)); //true
            }
        }
        

        equals() i klasa String

        Klasa String jest specyficznym typem obiektowym, w którym w niektórych sytuacjach porównanie przy pomocy operatora == zwróci true. Stanie się tak zawsze wtedy, kiedy obiekty tworzymy poprzez literały lub użyjemy metody intern().

        String first = "Napis";
        String second = "Napis";
        System.out.println(first == second); //true
        System.out.println(first.equals(second)); //true
        

        Jeśli jednak napisy wczytywane są do naszej aplikacji np. z pliku, konsoli, czy innego źródła, to porównanie przy pomocy == będzie już niewystarczające.

        Scanner scan = new Scanner(System.in);
        String first = scan.nextLine(); //"abc"
        String second = scan.nextLine(); //"abc"
        System.out.println(first == second); //false
        System.out.println(first.equals(second)); //true
        

        Generowanie metody equals() w eclipse

        Metoda equals() jest tam schematyczna i często wykorzystywana, że na szczęście da się ją wygenerować w każdym popularnym środowisku. Zamiast ją generować można także skorzystać z biblioteki Lombok.

        W eclipse należy skorzystać z zakładki Source > Generate hashCode() and equals() lub użyć skrótu klawiaturowego Alt + Shift + S.

        equals eclipse

        Generowanie metody equals() w IntelliJ IDEA

        Podobna opcja dostępna jest w Intellij IDEA, jednak tym razem wybieramy opcję Code > Generate > equals() and hashCode() lub można użyć skrótu Alt + Insert.

        equals intellij

        Kontrakt equals() i hashCode()

        Zauważ, że środowiska zawsze generują dwie metody i oprócz equals tworzona jest dodatkowo hashCode. Pomiędzy tymi zachodzi kontrakt mówiący o tym, że jeżeli dwa obiekty porównywane przy pomocy equals zwracają true, to ich metody hashCode powinny zwrócić równe sobie wartości.

        Zapisz się do newslettera

        Otrzymuj nasz Newsletter z przykładowymi pytaniami rekrutacyjnymi, wyzwaniami programistycznymi i nowościami ze świata Javy, a także informacje o nowych kursach i promocjach.

        Traktujemy Twoją prywatność poważnie. Nikomu nie udostępniamy Twojego maila no i zawsze możesz się wypisać.

        Komentarze do artykułu

        Wyłączyliśmy możliwość dodawania komentarzy. Poniżej znajdziesz archiwalne wpisy z czasów gdy strona była jeszcze hobbystycznym blogiem. Zapraszamy natomiast do zadawnia pytań i dyskusji na naszej grupe na facebooku.

        Szkolenie Java WrocławJavaStart na Youtube