Dlaczego muszę nadpisywać metody equals i hashCode w Javie?

[[2]} ostatnio przeczytałem to Developer Works Document .

W dokumencie chodzi o skuteczne i poprawne zdefiniowanie hashCode() i equals(), jednak nie jestem w stanie zrozumieć, dlaczego musimy nadpisać te dwie metody.

Jak mogę podjąć decyzję o skutecznym wdrożeniu tych metod?

Author: Exploring, 2010-02-15

29 answers

Joshua Bloch mówi o efektywnej Javie

Musisz nadpisać hashCode () w każdej klasie, która nadpisuje equals (). Niezastosowanie się do tego będzie skutkowało naruszeniem ogólnej Umowy o rzecz.hashCode(), które uniemożliwi poprawne działanie klasy w połączeniu ze wszystkimi kolekcjami bazującymi na hash, w tym HashMap, HashSet i Hashtable.

Spróbujmy to zrozumieć na przykładzie tego, co by się stało, gdybyśmy nadpisali equals() bez nadpisywania hashCode() i spróbuj użyć Map.

Powiedzmy, że mamy klasę taką jak ta i że dwa obiekty MyClass są równe, jeśli ich importantField jest równe (z hashCode() i equals() wygenerowane przez eclipse)

public class MyClass {

    private final String importantField;
    private final String anotherField;

    public MyClass(final String equalField, final String anotherField) {
        this.importantField = equalField;
        this.anotherField = anotherField;
    }

    public String getEqualField() {
        return importantField;
    }

    public String getAnotherField() {
        return anotherField;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result
                + ((importantField == null) ? 0 : importantField.hashCode());
        return result;
    }

    @Override
    public boolean equals(final Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        final MyClass other = (MyClass) obj;
        if (importantField == null) {
            if (other.importantField != null)
                return false;
        } else if (!importantField.equals(other.importantField))
            return false;
        return true;
    }

}

Tylko nadpisywanie equals

Jeśli tylko equals jest nadpisane, to kiedy wywołasz myMap.put(first,someValue) najpierw będzie hash do jakiegoś wiadra, a kiedy wywołasz {[12] } będzie hash do innego wiadra(ponieważ mają inny hashCode). Tak więc, chociaż są równe, ponieważ nie pasują do tego samego bucket, mapa nie zda sobie z tego sprawy i obaj zostają na mapie.


Chociaż nie jest konieczne nadpisywanie equals() jeśli nadpisujemy hashCode(), zobaczmy, co stanie się w tym konkretnym przypadku, gdy wiemy, że dwa obiekty MyClass są równe, jeśli ich importantField są równe, ale nie nadpisujemy equals().

Tylko nadpisywanie hashCode

Wyobraź sobie, że masz to

MyClass first = new MyClass("a","first");
MyClass second = new MyClass("a","second");

Jeśli tylko nadpisujesz hashCode to po wywołaniu myMap.put(first,someValue) najpierw bierze, oblicza jego hashCode i przechowuje go w danym wiadrze. Następnie, gdy wywołujesz myMap.put(second,someOtherValue) powinno ono zastąpić pierwsze na drugie zgodnie z dokumentacją Map , ponieważ są one równe (zgodnie z wymogiem biznesowym).

Ale problem polega na tym, że equals nie został przedefiniowany, więc gdy mapa hashuje second i iteruje przez wiadro szukając, czy istnieje obiekt k taki, że second.equals(k) jest prawdą, nie znajdzie żadnego, ponieważ second.equals(first) będzie false.

Hope it was clear

 435
Author: Lombo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-21 19:44:55

Kolekcje takie jak HashMap i HashSet używają wartości hashcode obiektu do określenia, w jaki sposób obiekt powinien być przechowywany w kolekcji, a hashcode jest ponownie używany do zlokalizowania obiektu w kolekcji.

Odzyskiwanie hashowania jest procesem dwuetapowym.
  1. znajdź właściwe wiadro (używając hashCode ())
  2. Przeszukaj wiadro w poszukiwaniu odpowiedniego elementu (używając equals ())

Oto mały przykład, Dlaczego powinniśmy overrride equals () i hashcode ().Rozważ klasę pracownika, która ma dwa pola wiek i nazwa.

public class Employee {

    String name;
    int age;

    public Employee(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == this)
            return true;
        if (!(obj instanceof Employee))
            return false;
        Employee employee = (Employee) obj;
        return employee.getAge() == this.getAge()
                && employee.getName() == this.getName();
    }

    // commented    
    /*  @Override
        public int hashCode() {
            int result=17;
            result=31*result+age;
            result=31*result+(name!=null ? name.hashCode():0);
            return result;
        }
     */
}

Teraz Utwórz klasę, Wstaw Obiekt pracownika do HashSet i sprawdź, czy ten obiekt jest obecny, czy nie.

public class ClientTest {
    public static void main(String[] args) {
        Employee employee = new Employee("rajeev", 24);
        Employee employee1 = new Employee("rajeev", 25);
        Employee employee2 = new Employee("rajeev", 24);

        HashSet<Employee> employees = new HashSet<Employee>();
        employees.add(employee);
        System.out.println(employees.contains(employee2));
        System.out.println("employee.hashCode():  " + employee.hashCode()
        + "  employee2.hashCode():" + employee2.hashCode());
    }
}

Wydrukuje

false
employee.hashCode():  321755204  employee2.hashCode():375890482

Teraz odkomentuj metodę hashcode (), wykonaj to samo, a wynikiem będzie

true
employee.hashCode():  -938387308  employee2.hashCode():-938387308

Teraz widzisz, dlaczego jeśli dwa obiekty są uważane za równe, ich hashcody muszą być równym? W przeciwnym razie nigdy nie będziesz w stanie znaleźć obiektu, ponieważ default metoda hashcode w obiekcie klasy praktycznie zawsze pojawia się z unikalnym numerem dla każdego obiektu, nawet jeśli metoda equals() jest nadpisana w taki sposób, że dwa lub więcej obiektów uważa się za równe. Nie ma znaczenia, jak równe są obiekty, jeśli ich hashcody tego nie odzwierciedlają. Więc jeszcze raz: jeśli dwa obiekty są równe, ich hashcodes muszą być również równe.

 141
Author: rajeev pani..,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-27 17:35:50

Musisz nadpisać hashCode() w każdym klasa, która nadpisuje equals (). Porażka takie postępowanie będzie skutkowało naruszeniem general contract for Obiekt.hashCode (), który zapobiegnie twoja klasa z poprawnego funkcjonowania w połączeniu ze wszystkimi hash-based kolekcje, w tym HashMap, HashSet i Hashtable.


from Effective Java , by Joshua Bloch

Definiując equals() i hashCode() konsekwentnie, możesz poprawić użyteczność Twoich klas jako kluczy w kolekcjach opartych na hash. Jak wyjaśnia dokument API dla hashCode: "ta metoda jest obsługiwana z korzyścią dla hashtables, takich jak te dostarczone przez java.util.Hashtable."

Najlepszą odpowiedzią na twoje pytanie o to, jak efektywnie zaimplementować te metody jest sugerowanie przeczytania rozdziału 3 Effective Java.

 47
Author: JuanZe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-24 12:53:02

Mówiąc najprościej, equals-metoda w obiekcie sprawdza równość odniesienia, gdzie jako dwie instancje twojej klasy mogą być semantycznie równe, gdy właściwości są równe. Jest to na przykład ważne podczas umieszczania obiektów w kontenerze, który wykorzystuje equals i hashcode, jak HashMap i Set. Powiedzmy, że mamy klasę:

public class Foo {
    String id;
    String whatevs;

    Foo(String id, String whatevs) {
        this.id = id;
        this.whatevs = whatevs;
    }
}

Tworzymy dwie instancje o tym samym id :

Foo a = new Foo("id", "something");
Foo b = new Foo("id", "something else");

Bez nadrzędnych równości jesteśmy getting:

  • A.równa się (b) jest fałszywa, ponieważ są to dwie różne instancje
  • A.equals(a) jest prawdziwe, ponieważ jest to ta sama instancja
  • B.równa się (b) jest prawdą, ponieważ jest to ta sama instancja
Zgadza się? Może, jeśli tego chcesz. Ale załóżmy, że chcemy, aby obiekty o tym samym id były tym samym obiektem, niezależnie od tego, czy są to dwie różne instancje. Nadpisujemy equals (i hashcode):
public class Foo {
    String id;
    String whatevs;

    Foo(String id, String whatevs) {
        this.id = id;
        this.whatevs = whatevs;
    }

    @Override
    public boolean equals(Object other) {
        if (other instanceof Foo) {
            return ((Foo)other).id.equals(this.id);   
        }
    }

    @Override
    public int hashCode() {
        return this.id.hashCode();
    }
}

Co do implementacji equals i hashcode mogę polecam korzystanie z Guava ' s helper metody

 18
Author: crunchdog,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-23 10:53:07

Tożsamość to nie równość.

  • równa się operator == tożsamość testowa.
  • equals(Object obj) metoda porównuje test równości (tzn. musimy stwierdzić równość przez nadpisanie metody)

Dlaczego muszę nadpisywać metody equals i hashCode w Javie?

Najpierw musimy zrozumieć użycie metody equals.

W celu identyfikacji różnic pomiędzy dwoma obiektami musimy nadpisać metodę equals.

Na przykład:

Customer customer1=new Customer("peter");
Customer customer2=customer1;
customer1.equals(customer2); // returns true by JVM. i.e. both are refering same Object
------------------------------
Customer customer1=new Customer("peter");
Customer customer2=new Customer("peter");
customer1.equals(customer2); //return false by JVM i.e. we have two different peter customers.

------------------------------
Now I have overriden Customer class equals method as follows:
 @Override
    public boolean equals(Object obj) {
        if (this == obj)   // it checks references
            return true;
        if (obj == null) // checks null
            return false;
        if (getClass() != obj.getClass()) // both object are instances of same class or not
            return false;
        Customer other = (Customer) obj;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name)) // it again using bulit in String object equals to identify the difference 
            return false;
        return true; 
    }
Customer customer1=new Customer("peter");
Customer customer2=new Customer("peter");
Insteady identify the Object equality by JVM, we can do it by overring equals method.
customer1.equals(customer2);  // returns true by our own logic

Teraz metoda hashCode może łatwo zrozumieć.

HashCode tworzy liczbę całkowitą w celu przechowywania obiektów w strukturach danych, takich jak HashMap, HashSet .

Załóżmy, że mamy metodę override equals z Customer Jak wyżej,

customer1.equals(customer2);  // returns true by our own logic

Podczas pracy ze strukturą danych, gdy przechowujemy obiekt w buckets (bucket to wymyślna nazwa folderu). Jeśli używamy wbudowanej techniki hash, dla powyżej dwóch klientów generuje ona dwa inny hashcode. Przechowujemy więc ten sam, identyczny obiekt w dwóch różnych miejscach. Aby uniknąć tego typu problemów powinniśmy nadpisać metodę hashCode również na podstawie następujących zasad.

  • un-equal instancje mogą mieć ten sam hashcode.
  • równe instancje powinny zwracać ten sam hashcode.
 14
Author: Premraj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-25 02:28:32

Ok, pozwól, że wyjaśnię to pojęcie w bardzo prostych słowach.

Po pierwsze z szerszej perspektywy mamy zbiory, a hashmap jest jedną z struktur danych w zbiorach.

Aby zrozumieć, dlaczego musimy nadpisać metodę equals i hashcode, jeśli trzeba najpierw zrozumieć, co to jest hashmap, a co robi.

Hashmap jest strukturą danych, która przechowuje pary kluczowych wartości danych w sposób TABLICOWY. Powiedzmy a [], gdzie każdy element w 'a' jest wartością klucza para.

Również każdy indeks w powyższej tablicy może być połączony listą, dzięki czemu ma więcej niż jedną wartość w jednym indeksie.

Dlaczego używa się hashmapy? Jeśli mamy szukać pomiędzy dużą tablicą, to przeszukiwanie każdej z nich nie będzie efektywne, więc co mówi nam technika hash, która pozwala wstępnie przetworzyć tablicę z pewną logiką i grupować elementy oparte na tej logice, tj.]}

Np: mamy tablicę 1,2,3,4,5,6,7,8,9,10,11 i stosujemy funkcję haszującą mod 10 więc 1,11 będzie być zgrupowane razem. Więc gdybyśmy mieli szukać 11 w poprzedniej tablicy, musielibyśmy iterację całej tablicy, ale kiedy ją grupujemy, ograniczamy nasz zakres iteracji, zwiększając tym samym szybkość. Ta struktura danych używana do przechowywania wszystkich powyższych informacji może być traktowana jako tablica 2d dla uproszczenia

Teraz oprócz powyższego hashmap mówi również, że nie będzie dodawać żadnych duplikatów w nim. I to jest główny powód, dla którego musimy nadpisać equals i hashcode

Więc kiedy jego powiedział, że wyjaśnia wewnętrzne działanie hashmap, musimy znaleźć, Jakie metody ma hashmap i jak postępuje zgodnie z powyższymi zasadami, które wyjaśniłem powyżej

Tak więc hashmap ma metodę wywołaną jako put (K, V)i zgodnie z hashmap powinien postępować zgodnie z powyższymi zasadami wydajnej dystrybucji tablicy i nie dodawać żadnych duplikatów

To, co put robi, to to, że najpierw wygeneruje hashcode dla danego klucza, aby zdecydować, w którym indeksie powinna się znaleźć wartość.jeśli nic nie jest obecne w tym indeksie wtedy nowa wartość zostanie dodana tam, jeśli coś jest już tam obecne wówczas nowa wartość powinna być dodana po końcu linkowanej listy w tym indeksie. ale pamiętaj, że nie należy dodawać duplikatów zgodnie z pożądanym zachowaniem hashmapy. powiedzmy więc, że masz dwa obiekty całkowite aa = 11, bb=11. jak każdy obiekt pochodzący z klasy object, domyślną implementacją do porównywania dwóch obiektów jest to, że porównuje wartości odniesienia, a nie wewnątrz obiekt. Tak więc w powyższym przypadku zarówno semantycznie równe, jak i możliwość, że dwa obiekty o tym samym hashcode i tych samych wartościach powstaną w ten sposób tworząc duplikaty. Jeśli obejdziemy, unikniemy dodawania duplikatów. Możesz również odnieść się do szczegóły pracy

import java.util.HashMap;


public class Employee {

String name;
String mobile;
public Employee(String name,String mobile) {
    this.name=name;
    this.mobile=mobile;
}

@Override
public int hashCode() {
    System.out.println("calling hascode method of Employee");
    String str=this.name;
    Integer sum=0;
    for(int i=0;i<str.length();i++){
        sum=sum+str.charAt(i);
    }
    return sum;

}
@Override
public boolean equals(Object obj) {
    // TODO Auto-generated method stub
    System.out.println("calling equals method of Employee");
    Employee emp=(Employee)obj;
    if(this.mobile.equalsIgnoreCase(emp.mobile)){

        System.out.println("returning true");
        return true;
    }else{
        System.out.println("returning false");
        return false;
    }


}

public static void main(String[] args) {
    // TODO Auto-generated method stub

    Employee emp=new Employee("abc", "hhh");
    Employee emp2=new Employee("abc", "hhh");
    HashMap<Employee, Employee> h=new HashMap<>();
    //for (int i=0;i<5;i++){
        h.put(emp, emp);
        h.put(emp2, emp2);

    //}

    System.out.println("----------------");
    System.out.println("size of hashmap: "+h.size());


}

}
 11
Author: Chetan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-03 18:33:17

hashCode() :

Jeśli tylko nadpisasz metodę hash-code, nic się nie stanie. Ponieważ zawsze zwraca new hashCode dla każdego obiektu jako klasę obiektu.

equals() :

Jeśli tylko nadpisujesz metodę equal, a.equals(b) jest prawdą, oznacza to, że hashCode z a i b muszą być takie same, ale się nie zdarzają. Ponieważ nie nadpisałeś metody hashCode.

Notatka: hashCode() metoda klasy obiektu zawsze zwraca Nowy hashCode dla każdego obiektu.

Więc kiedy musisz użyć swojego obiektu w zbiór bazujący na hashowaniu musi nadpisać zarówno equals(), jak i hashCode().

 11
Author: Rinkal Gupta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-25 10:50:23

W celu użycia własnych obiektów klasy jako kluczy w kolekcjach takich jak HashMap, Hashtable itp.. , powinniśmy nadpisać obie metody (hashCode () i equals ()) mając świadomość wewnętrznego działania kolekcji. W przeciwnym razie prowadzi to do błędnych rezultatów, których się nie spodziewamy.

 6
Author: Prashanth - codeforeach.com,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-11 09:38:54

Ponieważ jeśli ich nie nadpisasz, użyjesz domyślnej implantacji w obiekcie.

Biorąc pod uwagę, że równość instancji i wartości hascode na ogół wymagają wiedzy o tym, co składa się na obiekt, będą one musiały zostać przedefiniowane w twojej klasie, aby miały jakiekolwiek wymierne znaczenie.

 5
Author: PaulJWilliams,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-15 11:20:56

Java stawia regułę, że

"Jeżeli dwa obiekty są sobie równe używając metody Object class equals, wtedy metoda hashcode powinna dać taką samą wartość dla tych dwóch obiektów."

Tak więc, jeśli w naszej klasie nadpisujemy równe, powinniśmy nadpisać metodę hashcode również, aby ta reguła została zachowana. Obie te metody equals i {[1] } są używane w Hashtable do przechowywania wartości jako pary klucz-wartość.Jeśli nadpisamy jeden, a nie drugi, istnieje możliwość, że hashtable może nie działać tak, jak chcemy, jeśli użyjemy takiego obiektu jako key.

 5
Author: Ritesh Kaushik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-01 15:13:07

Dodawanie do odpowiedzi @ Lombo

kiedy trzeba nadpisać equals ()?

Domyślną implementacją obiektu equals () jest

public boolean equals(Object obj) {
        return (this == obj);
}

Co oznacza, że dwa obiekty będą uważane za równe tylko wtedy, gdy mają ten sam adres pamięci, który będzie prawdziwy tylko wtedy, gdy porównywanie obiektu z samym sobą.

Ale możesz rozważyć dwa obiekty takie same, jeśli mają taką samą wartość dla jednego lub więcej ich właściwości (Patrz przykład podany w odpowiedzi @Lombo).

Więc w takich sytuacjach obejdziesz equals() i podasz własne warunki równości.

udało mi się zaimplementować equals () i działa great.So dlaczego proszą o nadpisanie hashCode ()?

Well.As dopóki nie używasz kolekcji"Hash" na swojej klasie zdefiniowanej przez użytkownika, jest to w porządku. Ale za jakiś czas w przyszłości możesz użyć HashMap lub HashSet i jeśli jeśli nie override i "poprawnie zaimplementujesz" hashCode () , te zbiory oparte na Hashach nie będą działać zgodnie z przeznaczeniem.

Override only equals (Addition to @ Lombo 's answer)

myMap.put(first,someValue)
myMap.contains(second); --> But it should be the same since the key are the same.But returns false!!! How?

Po pierwsze,HashMap sprawdza czy hashCode second jest taki sam jak first. Tylko wtedy, gdy wartości są takie same, rozpocznie się sprawdzanie równości w tym samym zasobniku.

Ale tutaj hashCode jest inny dla tych 2 obiektów (ponieważ mają inną pamięć adres-z domyślnej implementacji). Dlatego nie będzie nawet dbać o sprawdzenie równości.

Jeśli masz punkt przerwania wewnątrz metody overridden equals (), nie pojawi się on, jeśli mają inne hashcody. contains() sprawdza hashCode() i tylko jeśli są takie same, wywoła Twoją metodę equals().

dlaczego nie możemy sprawdzić równości we wszystkich wiadrach? Nie ma więc potrzeby, abym nadpisywał hashCode ()!!

Wtedy jesteś brakuje punktu zbiorów opartych na Hash. Rozważmy następujące :

Your hashCode() implementation : intObject%9.

Poniżej znajdują się klucze przechowywane w formie wiadra.

Bucket 1 : 1,10,19,... (in thousands)
Bucket 2 : 2,20,29...
Bucket 3 : 3,21,30,...
...

Powiedz, chcesz wiedzieć, czy mapa zawiera klucz 10. Chcesz przeszukać wszystkie wiadra? a może chcesz przeszukać tylko jedno wiadro?

Na podstawie hashCode, można określić, że jeśli 10 jest obecny, musi być obecny w Bucket 1. Więc tylko wiadro 1 będzie przeszukiwane !!

 5
Author: user104309,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-09 06:14:37
class A {
    int i;
    // Hashing Algorithm
    if even number return 0 else return 1
    // Equals Algorithm,
    if i = this.i return true else false
}
  • put ('key',' value') obliczy wartość skrótu używając hashCode() do określenia bucket and uses equals() method to find whether the value is already obecny w wiadrze. Jeśli nie, zostanie dodany else, zostanie zastąpiony bieżącą wartością
  • get ('key') użyje hashCode(), aby znaleźć wpis (bucket) jako pierwszy i equals() aby znaleźć wartość we wpisie

Jeśli oba są nadpisane,

Mapa A >

Map.Entry 1 --> 1,3,5,...
Map.Entry 2 --> 2,4,6,...

If equals is not overridden

Mapa A >

Map.Entry 1 --> 1,3,5,...,1,3,5,... // Duplicate values as equals not overridden
Map.Entry 2 --> 2,4,6,...,2,4,..

Jeśli hashCode nie jest nadpisany

Mapa A >

Map.Entry 1 --> 1
Map.Entry 2 --> 2
Map.Entry 3 --> 3
Map.Entry 4 --> 1
Map.Entry 5 --> 2
Map.Entry 6 --> 3 // Same values are Stored in different hasCodes violates Contract 1
So on...

HashCode Equal Contract

  1. dwa klucze równe według metody equal powinny wygenerować ten sam hashCode
  2. dwa klucze generujące ten sam hashCode nie muszą być sobie równe (w powyższym przykładzie wszystkie liczby parzyste generują ten sam hash)
 5
Author: bharanitharan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-14 09:31:58

Metody Equals i Hashcode w Javie

Są to metody Javy.lang.Klasa obiektowa, która jest superklasą wszystkich klas (również klas niestandardowych i innych zdefiniowanych w java API).

Realizacja:

Public Boolean equals (Object obj)

Public int hashCode ()

Tutaj wpisz opis obrazka

Public boolean equals (Object obj)

Ta metoda po prostu sprawdza, czy dwa obiekty odwołują się do x i y odnoszą się do tego samego obiektu. tzn. sprawdza czy x = = y.

jest to refleksyjne: dla dowolnej wartości referencyjnej x, x. równa się (x) powinna zwracać true.

jest symetryczny: dla dowolnych wartości referencyjnych x i y, x. equals (y) powinno zwracać true wtedy i tylko wtedy, gdy y.equals(x) zwraca true.

jest przechodni: dla dowolnych wartości referencyjnych x, y i z, Jeśli x. equals(y) zwraca true, a y. equals(z) zwraca true, to x. equals (z) powinno zwracać true.

on consistent: dla dowolnych wartości referencyjnych x i y, wielokrotne wywołania x. equals (y) konsekwentnie zwracają true lub konsekwentnie zwracają false, pod warunkiem, że żadne informacje użyte w porównaniach equals na obiekcie nie zostaną zmodyfikowane.

Dla każdej innej niż null wartości referencyjnej x, X. equals(null) powinno zwracać fałsz.

Public int hashCode()

Ta metoda zwraca wartość kodu hash dla obiektu, w którym ta metoda jest wywoływana. Ta metoda zwraca kod hash wartość jako liczba całkowita i jest obsługiwana na rzecz klas kolekcji opartych na hashowaniu, takich jak Hashtable, HashMap, HashSet itp. Ta metoda musi być nadpisana w każdej klasie, która nadpisuje metodę equals.

Ogólna umowa hashCode to:

Ilekroć jest wywoływana na tym samym obiekcie więcej niż jeden raz podczas wykonywania aplikacji Java, metoda hashCode musi konsekwentnie zwracać tę samą liczbę całkowitą, pod warunkiem, że żadne informacje nie są używane w porównaniach równości na obiekt został zmodyfikowany.

Ta liczba całkowita nie musi pozostawać spójna od jednego wykonania aplikacji do innego wykonania tej samej aplikacji.

Jeżeli dwa obiekty są równe według metody equals( Object), to wywołanie metody hashCode na każdym z dwóch obiektów musi dać taki sam wynik liczb całkowitych.

Nie jest wymagane, aby Jeśli dwa obiekty są nierówne zgodnie z równymi (java.lang.Obiekt) metodę, następnie wywołanie metody hashCode na każdej z dwóch obiekty muszą wytwarzać różne wyniki liczb całkowitych. Programista powinien jednak mieć świadomość, że generowanie odrębnych wyników całkowitych dla nierównych obiektów może poprawić wydajność hashtabli.

Równe obiekty muszą wytwarzać ten sam kod hash, o ile są równe, choć nierówne obiekty nie muszą wytwarzać odrębnych kodów skrótu.

Zasoby:

JavaRanch

Zdjęcie

 5
Author: Aftab Virtual,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-28 06:13:51

Rozważmy kolekcję kulek w wiaderku w kolorze czarnym. Twoim zadaniem jest pokolorowanie tych kulek w następujący sposób i użycie ich do odpowiedniej gry,

Do Tenisa-Żółty, Czerwony. Do Krykieta-Biały

Teraz wiadro ma kulki w trzech kolorach żółtym, czerwonym i białym. I że teraz zrobiłeś kolorowanie tylko wiesz, który kolor jest dla której gry.

Kolorowanie kulek - haszowanie. Wybór piłki do gry-równa.

Jeśli zrobiłeś kolorowankę i ktoś wybiera piłka do krykieta lub tenisa nie będą zwracać uwagi na kolor!!!

 4
Author: bharanitharan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-09 06:02:47

Szukałem wyjaśnienia " jeśli nadpisujesz tylko hashCode, to po wywołaniu myMap.put(first,someValue) najpierw bierze, oblicza swój hashCode i przechowuje go w danym wiadrze. Po wywołaniu myMap.put(first,someOtherValue) powinno ono zastąpić first na second zgodnie z dokumentacją mapy, ponieważ są równe (zgodnie z naszą definicją)." :

Myślę, że po raz drugi kiedy dodajemy w {[2] } to powinien to być "drugi" obiekt jak myMap.put(second,someOtherValue)

 4
Author: Narinder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-25 10:10:24

Jest przydatny przy użyciu Obiekty wartości. Poniżej znajduje się fragment z Portland Pattern repozytorium:

Przykładami obiektów wartości są rzeczy jak liczby, daty, pieniądze i struny. Zazwyczaj są małe przedmioty, które są dość szeroko stosowane. Ich tożsamość opiera się na ich stanie niż na ich tożsamości przedmiotu. W ten sposób możesz mieć wiele kopii tego samego obiektu wartości pojęciowej.

Więc mogę mieć wiele kopii obiekt, który przedstawia datę 16 stycznia 1998. Każda z tych kopii będzie równa sobie. Dla małego obiekt taki jak ten, jest często łatwiej tworzyć nowe i przenosić ich wokół zamiast polegać na pojedynczy obiekt do reprezentowania daty.

Obiekt value powinien zawsze nadpisywać .equals() w Javie (lub = w Smalltalku). (Pamiętaj o nadpisaniu .hashCode () jako cóż.)

 3
Author: Ionuț G. Stan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-15 11:24:51

Metody equals i hashcode są zdefiniowane w klasie obiektu. Domyślnie jeżeli metoda equals zwróci true, wtedy system pójdzie dalej i sprawdzi wartość kodu skrótu. Jeśli kod hash 2 obiektów jest taki sam tylko wtedy obiekty będą traktowane jako takie same. Jeśli więc nadpisujesz tylko metodę equals, to nawet jeśli nadpisana metoda equals wskazuje 2 obiekty , które mają być równe, to hashcode zdefiniowany w systemie może nie wskazywać, że 2 obiekty są równe. Więc musimy nadpisuje również kod hash.

 3
Author: Aarti,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-28 08:06:24

Załóżmy, że masz klasę (A), która agreguje dwa inne (B) (C) i musisz przechowywać instancje (A) w hashtable. Domyślna implementacja pozwala tylko na rozróżnienie instancji, ale nie przez (B) I (C). Więc dwie instancje A mogą być równe, ale domyślne nie pozwoli Ci porównać ich w prawidłowy sposób.

 2
Author: Dewfy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-15 11:22:07

W poniższym przykładzie, jeśli skomentujesz nadpisanie dla equals lub hashcode w klasie Person, kod ten nie sprawdzi porządku Toma. Używanie domyślnej implementacji hashcode może powodować błędy w wyszukiwaniu hashtable.

To, co mam poniżej, to uproszczony kod, który wyciąga kolejność ludzi według osoby. Osoba jest używana jako klucz w hashtable.

public class Person {
    String name;
    int age;
    String socialSecurityNumber;

    public Person(String name, int age, String socialSecurityNumber) {
        this.name = name;
        this.age = age;
        this.socialSecurityNumber = socialSecurityNumber;
    }

    @Override
    public boolean equals(Object p) {
        //Person is same if social security number is same

        if ((p instanceof Person) && this.socialSecurityNumber.equals(((Person) p).socialSecurityNumber)) {
            return true;
        } else {
            return false;
        }

    }

    @Override
    public int hashCode() {        //I am using a hashing function in String.java instead of writing my own.
        return socialSecurityNumber.hashCode();
    }
}


public class Order {
    String[]  items;

    public void insertOrder(String[]  items)
    {
        this.items=items;
    }

}



import java.util.Hashtable;

public class Main {

    public static void main(String[] args) {

       Person p1=new Person("Tom",32,"548-56-4412");
        Person p2=new Person("Jerry",60,"456-74-4125");
        Person p3=new Person("Sherry",38,"418-55-1235");

        Order order1=new Order();
        order1.insertOrder(new String[]{"mouse","car charger"});

        Order order2=new Order();
        order2.insertOrder(new String[]{"Multi vitamin"});

        Order order3=new Order();
        order3.insertOrder(new String[]{"handbag", "iPod"});

        Hashtable<Person,Order> hashtable=new Hashtable<Person,Order>();
        hashtable.put(p1,order1);
        hashtable.put(p2,order2);
        hashtable.put(p3,order3);

       //The line below will fail if Person class does not override hashCode()
       Order tomOrder= hashtable.get(new Person("Tom", 32, "548-56-4412"));
        for(String item:tomOrder.items)
        {
            System.out.println(item);
        }
    }
}
 2
Author: developer747,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-24 13:25:21

1) częsty błąd pokazano w poniższym przykładzie.

public class Car {

    private String color;

    public Car(String color) {
        this.color = color;
    }

    public boolean equals(Object obj) {
        if(obj==null) return false;
        if (!(obj instanceof Car))
            return false;   
        if (obj == this)
            return true;
        return this.color.equals(((Car) obj).color);
    }

    public static void main(String[] args) {
        Car a1 = new Car("green");
        Car a2 = new Car("red");

        //hashMap stores Car type and its quantity
        HashMap<Car, Integer> m = new HashMap<Car, Integer>();
        m.put(a1, 10);
        m.put(a2, 20);
        System.out.println(m.get(new Car("green")));
    }
}

Zielony samochód nie został znaleziony

2. Problem spowodowany hashCode()

Problem jest spowodowany przez metodę un-overridden hashCode(). Umowa pomiędzy equals() A hashCode() wynosi:

  1. Jeśli dwa obiekty są sobie równe, to muszą mieć ten sam kod skrótu.
  2. Jeśli dwa obiekty mają ten sam kod skrótu, mogą być równe lub nie.

    public int hashCode(){  
      return this.color.hashCode(); 
    }
    
 2
Author: Neeraj Gahlawat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-28 06:19:15

Klasa String i klasa wrappera mają inną implementację metod equals() i hashCode() niż Klasa obiektowa. equals () metoda klasy obiektu porównuje odwołania do obiektów, Nie zawartość. metoda hashCode () klasy obiektu zwraca odrębny hashcode dla każdego pojedynczego obiektu, niezależnie od tego, czy zawartość jest taka sama.

To prowadzi problem, gdy używasz kolekcji Map i klucz jest typu Persistent, typu StringBuffer / builder. Ponieważ nie nadpisują equals () i hashCode () w przeciwieństwie Klasa String, equals() zwróci false, gdy porównasz dwa różne obiekty, mimo że oba mają tę samą zawartość. Spowoduje to, że hashMap przechowuje te same klucze zawartości. Przechowywanie tych samych kluczy treści oznacza, że narusza to regułę Map, ponieważ Map w ogóle nie zezwala na powielanie kluczy. Dlatego nadpisujesz metody equals() oraz hashCode () w swojej klasie i dostarczasz implementację (IDE może wygenerować te metody) tak, że działają one tak samo jak equals() i hashCode () i zapobiegają tym samym klawisze zawartości.

Musisz nadpisać metodę hashCode() wraz z equals (), ponieważ equals () działa zgodnie z hashcode.

Ponadto nadpisanie metody hashCode() wraz z equals() pomaga w nienaruszeniu umowy equals()-hashCode (): "jeśli dwa obiekty są równe, to muszą mieć ten sam kod skrótu."

Kiedy trzeba napisać niestandardową implementację dla hashCode ()?

Jak wiemy, wewnętrzna praca HashMap opiera się na Hashowaniu. Są niektóre wiadra, w których przechowywane są zestawy wejściowe. Dostosowujesz implementację hashCode() zgodnie ze swoimi wymaganiami, aby Obiekty tej samej kategorii mogły być przechowywane w tym samym indeksie. w przypadku zapisywania wartości do kolekcji Map przy użyciu metody put(k,v), wewnętrzna implementacja put () wynosi:

put(k, v){
hash(k);
index=hash & (n-1);
}

Oznacza, że generuje indeks i indeks jest generowany na podstawie hashcode konkretnego obiektu klucza. Tak więc, aby ta metoda generowała hashcode zgodnie z wymaganiami, ponieważ same entrysets hashcode będą przechowywane w tym samym zasobniku lub indeksie.

To jest to!
 2
Author: Arun Raaj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-02 08:30:26

Powodem tego: Gdy pola obiektu mogą być null, implementacja obiektu.równe mogą być bolesne, ponieważ musisz sprawdzić oddzielnie dla null. Korzystanie Z Obiektów.equal pozwala na wykonywanie sprawdzeń equals w sposób wrażliwy na null, bez ryzyka wystąpienia NullPointerException. Objects.equal("a", "a"); // returns true Objects.equal(null, "a"); // returns false Objects.equal("a", null); // returns false Objects.equal(null, null); // returns true

 1
Author: aman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-24 05:57:57

hashCode() metoda służy do uzyskania unikalnej liczby całkowitej dla danego obiektu. Ta liczba całkowita jest używana do określenia położenia kubełka, gdy obiekt ten musi być przechowywany w niektórych HashTable, HashMap Jak struktura danych. Domyślnie zwraca metodę hashCode() obiektu i całkowitą reprezentację adresu pamięci, w którym obiekt jest przechowywany.

Metoda hashCode() obiektów jest używana gdy wstawiamy je do HashTable, HashMap lub HashSet. Więcej o HashTables na Wikipedia.org w celach informacyjnych.

Aby wstawić dowolny wpis w strukturze danych mapy potrzebujemy zarówno klucza, jak i wartości. Jeśli zarówno klucz, jak i wartości są typami danych zdefiniowanymi przez użytkownika, to hashCode() klucza będzie określać, gdzie wewnętrznie przechowywać obiekt. Gdy wymagane jest również wyszukanie obiektu z mapy, kod skrótu klucza będzie określał, gdzie szukać obiektu.

Kod hashowy wskazuje tylko na określony "obszar" (lub listę, wiadro itp.) wewnętrznie. Ponieważ różne obiekty klucza mogą potencjalnie mieć ten sam kod hash, sam kod hash nie jest gwarancja znalezienia odpowiedniego klucza. HashTable następnie iteruje ten obszar (wszystkie klucze z tym samym kodem skrótu) i używa metody equals() klucza, aby znaleźć odpowiedni klucz. Po znalezieniu właściwego klucza zwracany jest obiekt zapisany dla tego klucza.

Tak więc, jak widzimy, kombinacja metod hashCode() i equals() jest używana podczas przechowywania i wyszukiwania obiektów w HashTable.

Uwagi:

  1. Zawsze używaj tych samych atrybutów obiektu do generowania hashCode() i equals(). Podobnie jak w naszym przypadku, użyliśmy identyfikatora pracownika.

  2. equals() musi być spójne(jeżeli obiekty nie są modyfikowane, wtedy musi zwracać tę samą wartość).

  3. Ilekroć a.equals(b), to a.hashCode() musi być takie samo jak b.hashCode().

  4. Jeśli obejdziesz jeden, powinieneś obejść drugi.

Http://parameshk.blogspot.in/2014/10/examples-of-comparable-comporator.html

 1
Author: Paramesh Korrakuti,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-25 10:33:42

IMHO, jest tak jak mówi reguła-jeśli dwa obiekty są równe to powinny mieć ten sam hash, tzn. równe obiekty powinny wytwarzać równe wartości hash.

Podane powyżej, domyślne equals () w obiekcie to==, które porównuje adres, hashCode () zwraca adres w liczbie całkowitej (hash na rzeczywistym adresie), który jest ponownie odrębny dla odrębnego obiektu.

Jeśli chcesz użyć własnych obiektów w kolekcjach opartych na Hash, musisz nadpisać zarówno equals (), jak i hashCode(), przykład Jeśli chcę zachować HashSet obiektów pracowniczych, jeśli nie używam silniejszego hashCode i równe mogę znieść nadpisanie dwóch różnych obiektów pracowniczych, dzieje się tak, gdy używam wieku jako hashCode (), jednak powinienem używać unikalnej wartości, która może być identyfikatorem pracownika.

 1
Author: Cleonjoys,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-05 16:10:48

Aby pomóc ci sprawdzić duplikaty obiektów, potrzebujemy niestandardowych równości i hashCode.

Ponieważ hashcode zawsze zwraca liczbę, zawsze szybko można pobrać obiekt za pomocą liczby, a nie klucza alfabetycznego. Jak to zrobi? Załóżmy, że stworzyliśmy nowy obiekt przekazując jakąś wartość, która jest już dostępna w innym obiekcie. Teraz nowy obiekt zwróci tę samą wartość skrótu co inny obiekt, ponieważ przekazywana wartość jest taka sama. Po zwróceniu tej samej wartości hash, JVM za każdym razem przechodzi pod ten sam adres pamięci i jeśli w przypadku, gdy jest więcej niż jeden obiekt o tej samej wartości hash, użyje metody equals () do zidentyfikowania właściwego obiektu.

 1
Author: Tavash,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-19 02:27:15

Jeśli chcesz przechowywać i pobierać własny obiekt jako klucz w Map, zawsze powinieneś zastąpić równe i hashCode w swoim niestandardowym obiekcie . Eg:

Person p1 = new Person("A",23);
Person p2 = new Person("A",23);
HashMap map = new HashMap();
map.put(p1,"value 1");
map.put(p2,"value 2");

Tutaj p1 i p2 będą rozpatrywane jako tylko jeden obiekt, A map rozmiar będzie tylko 1, ponieważ są równe.

 0
Author: Ambrish Rajput,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-16 14:23:56
public class Employee {

    private int empId;
    private String empName;

    public Employee(int empId, String empName) {
        super();
        this.empId = empId;
        this.empName = empName;
    }

    public int getEmpId() {
        return empId;
    }

    public void setEmpId(int empId) {
        this.empId = empId;
    }

    public String getEmpName() {
        return empName;
    }

    public void setEmpName(String empName) {
        this.empName = empName;
    }

    @Override
    public String toString() {
        return "Employee [empId=" + empId + ", empName=" + empName + "]";
    }

    @Override
    public int hashCode() {
        return empId + empName.hashCode();
    }

    @Override
    public boolean equals(Object obj) {

        if (this == obj) {
            return true;
        }
        if (!(this instanceof Employee)) {
            return false;
        }
        Employee emp = (Employee) obj;
        return this.getEmpId() == emp.getEmpId() && this.getEmpName().equals(emp.getEmpName());
    }

}

Klasa Testowa

public class Test {

    public static void main(String[] args) {
        Employee emp1 = new Employee(101,"Manash");
        Employee emp2 = new Employee(101,"Manash");
        Employee emp3 = new Employee(103,"Ranjan");
        System.out.println(emp1.hashCode());
        System.out.println(emp2.hashCode());
        System.out.println(emp1.equals(emp2));
        System.out.println(emp1.equals(emp3));
    }

}

In Object Class equals (Object obj) służy do porównywania adresów, dlatego gdy w klasie testowej porównujemy dwa obiekty, to równa się metoda dająca false, ale gdy nadpisujemy hashcode (), może ona porównać zawartość i dać poprawny wynik.

 0
Author: Manash Ranjan Dakua,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-17 11:37:53

Obie metody są zdefiniowane w klasie obiektu. I oba są w najprostszej realizacji. Więc jeśli potrzebujesz, chcesz dodać więcej implementacji do tych metod, to masz nadpisanie w swojej klasie.

Dla EX: equals() metoda w obiekcie sprawdza jej równość tylko w referencji. Więc jeśli potrzebujesz porównać jego stan, jak również, to możesz nadpisać, że jak to jest zrobione w klasie String.

 -1
Author: GuruKulki,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-22 11:29:28

Bah -" musisz nadpisać hashCode () w każdej klasie, która nadpisuje equals ()."

[From Effective Java, by Joshua Bloch?]

Czy to nie jest źle? Nadpisanie hashCode prawdopodobnie oznacza, że piszesz klasę hash-key, ale nadpisywanie equals na pewno nie. Istnieje wiele klas, które nie są używane jako klucze hashowe, ale chcą metody testowania równości logicznej z innego powodu. Jeśli wybierzesz dla niego" equals", możesz zostać poproszony o napisanie hashCode wdrożenie przez nadgorliwe stosowanie tej zasady. Wszystko, co osiąga, to dodanie niesprawdzonego kodu do bazy kodowej, zło czekające na kogoś w przyszłości. Również pisanie kodu, którego nie potrzebujesz, jest anty-zwinne. Jest po prostu źle (a wygenerowany ide będzie prawdopodobnie niezgodny z Twoimi własnoręcznie wykonanymi równaniami).

Z pewnością powinni zlecić Interfejs na obiektach zapisanych do użycia jako klucze? Niezależnie od tego, obiekt nigdy nie powinien podawać domyślnego hashCode() i equals() imho. Prawdopodobnie zachęciło to wiele zbiórek łamanych haszyszu.

Ale w każdym razie, myślę ,że "reguła" jest zapisana od tyłu do przodu. W międzyczasie będę unikał używania "equals" dla metod testowania równości: - (

 -4
Author: Alan Dobbie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-19 18:00:16