В чем разница между оператором == и equals()? (с hashcode()???)

Я изучал hashcode более подробно и понял, что:

1. Если вы переопределите equals(), вы также должны переопределить hashcode().

2. Чтобы найти, если 2 объекта являются одним и тем же объектом, используйте == operator

Учитывая эти 2 фактора, в Java я предполагал, что когда == operator используется для сравнения , если два экземпляра одинаковы или нет,

if(object1 == object2)

на самом деле делает

if(object1.hashcode() == object2.hashcode())

Но, похоже, я ошибся, выполнив приведенный ниже тест.

public class Main {

    public static void main(String[] args){
        Obj1 one = new Obj1();
        Obj1 two = new Obj1();
        //is this calling hashCode() in backend???
        if(one == two) {
            System.out.println("same");
        }
        else {
            System.out.println("nope");
        }
        //this is of course return true
        if(one == one) {
            System.out.println("one and one is same");
        }
    }
}

class Obj1 {
    @Override
    public int hashCode() {
        System.out.println("hashCode() is called");
        return 111;
    }
    @Override
    public boolean equals(Object another) {
        System.out.println("equals() is called");
        return false;
    }
}

В соответствии с тестом, который использует == operator, и посмотрите, вызывается ли equals(), и это не так.

Итак, мой вопрос: если == operator может использоваться для сравнения, если объект тот же или нет, какова точка переопределения методов e quals() и hashCode() для сравнения? Разве не == operator выполняет работу?

ссылка:

Переопределение hashCode() - это достаточно хорошо?

http://mindprod.com/jgloss/hashcode.html

http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Object.html#equals(java.lang.Object)

Ответы

Ответ 1

Оператор == определяет, что 2 ссылки указывают на один и тот же объект.

Итак,

 Object o1 = new Object();
 Object o2 = o1;

 o1 == o2; //true

 o2 = new Object();

 o1 == o2 // false

метод Object.equals() "как определить, равны ли 2 ссылки на объекты, которые не являются одним и тем же объектом?"

Если две ссылки указывают на один и тот же объект, оба

o1 == o2 
o1.equals(o2) 

должно быть правдой.

Но если o1 и o2 не являются одним и тем же объектом, они все равно могут быть равными логически. Для любого заданного класса значения равно зависимости от семантики объекта. Например, рассмотрим класс, где поле1 и поле2 заданы пользователем, но поле 3 вычисляется и имеет случайный элемент для его вычисления. Возможно, имеет смысл определить равные в этом случае, чтобы они зависели только от полей1 и поля2, а не от поля3. Именно поэтому необходимо равное.

Ответ 2

== является тождеством.

.equals() является равенством.

.equals() по умолчанию используется только == (точно так же, как hashCode() по умолчанию - System.identityHashCode(), но вы можете переопределить их, если есть более осмысленный способ проверить равенство. Обычно это своего рода "структурное" равенство т.е. все части this .equal() для всех частей that?

Ответ 3

Если у вас еще нет копии; купите копию Эффективной Java от Джошуа Блоха.

Это фактическая ссылка для разработчиков Java и содержит много информации по этому (и многим другим) темам.

Ответ 4

== (используется для объектов, а не для примитивных значений) проверяет, являются ли 2 объекта фактически одним и тем же объектом; он сравнивает, указывают ли указатели на одну и ту же ячейку памяти.

.equals() определяется самим объектом.

String s1 = new String("Hello");
String s2 = new String("Hello");

boolean b1 = ( s1 == s2 ) ; // false: s1 and s2 point to different objects
boolean b2 = ( s1.equals(s2) ) ; // true: s1 and s2 both represent the same
                                 //       piece of text - "Hello"

.hashCode() - это трюк оптимизации (в большинстве случаев, в любом случае). A лот кода в стандартных библиотеках делает предположение, что если o1.equals(o2)==true then o1.hashCode()==o2.hashCode() и что если o1.hashCode()!=o2.hashCode(), то o1.equals(o2)==false, чтобы работать быстрее.

Наиболее очевидным примером такой оптимизации является класс HashMap. Это позволяет быстро восстановить объекты с помощью клавиши действительно, но сильно ломается, если hashCode и equals не работают должным образом для ключевых элементов. На самом деле, это одна из причин того, что класс String является неизменным: если вы смогли изменить String (и, следовательно, изменить его hashCode), в то время как String был ключом в HashMap, тогда вы никогда не сможете его найти, так как вы в конечном итоге искали бы его в неправильном месте!

Другие ответы рекомендуют Эффективная Java от Джошуа Блоха. Если вы задаете такие вопросы, то сейчас самое идеальное время в вашей карьере, чтобы купить книгу и прочитать ее на обложке. Также стоит пересчитать его через год или два, когда вы забудете об этом, и многое другое будет иметь смысл...

Ответ 5

Большинство из них уже ответили, вот и вот еще один иллюстрирующий пример:

String s1 = "foo";
String s2 = "foo";
System.out.println(s1 == s2); // true, because same reference (string pool)

String s3 = new String("foo");
String s4 = new String("foo");
System.out.println(s3 == s4); // false, because different reference
System.out.println(s3.equals(s4)); // true, because same value

Ответ 6

== оператор → проверяет погоду 2 ссылки указывают на один и тот же объект или нет. Если же он возвращает true, то в противном случае ложь.

equals( ) → проверяет как объект ссылки, так и объект состояния. Состояние слышимости означает данные объекта. В этом любое верно, оно возвращает true. В противном случае - false. Но мы должны переопределить equals( ) в нашем пользовательском объекте и написать соответствующий код.

Hashcode( ) → hashCode объекта представляет собой случайное число, которое может использоваться JVM при сохранении/добавлении объектов в хэш файлы, хэш-таблицы или Hashmap.

Пример hashcode()

class TestHasChode
{
int i;
TestHasChode(int i)
{
this.i = i;
}

public static void main(String arg[])
{  
    //before overriding hashcode()  
TestHasChode t1 = new TestHasChode(100);   
TestHasChode t2 = new TestHasChode(110);

System.out.println(t1); //[email protected]  
System.out.println(t2); //[email protected]  

TestHasChode t3 = new TestHasChode(100);  
TestHasChode t4 = new TestHasChode(100);  
System.out.println(t3); //[email protected]   
System.out.println(t4); //[email protected]

/*hashCode() of Object class implemented to return hashCode based on address of an object, but based
on our requirement we can override hashCode() to generate our own numbers as hashCodes*/

//after overriding hashcode()  
System.out.println(t3); //[email protected]  
System.out.println(t4); //[email protected]  
}  
public int hashCode(){
return i;
}  
}  
-->Example of equals()method      
class Student
{
String name;   
int rollno;   
Student(String name,int rollno)
{   
this.name = name;    
this.rollno = rollno;   
}   
public static void main(String arg[])
{       
    //before overrideng equals method    
Student s1 = new Student ("raju", 101);     
Student s2 = new Student ("giri", 102);     
Student s3 = new Student ("giri", 102);     
System.out.println(s1.equals(s2));//false    
System.out.println(s2.equals(s3));//false    
    //after overriding equals method    
System.out.println(s1.equals(s2));//false    
System.out.println(s2.equals(s3));//true-->hear overriding equals() checks state.so it is true.  
    //in string variables comparisition   
    String s4="hello";    
    String s5=new String("hello");    
    String s6=new String("hello");   
System.out.println(s4.equals(s5));//true--> because String class containg overridden equals method   
System.out.println(s5.equals(s6));//true-->even though differnet object reference but String class containg overridden equals method   

}     
public boolean equals(Object obj){   
String name1 = this.name;   
int rollno1 = this.rollno;   
Student s2 = (Student)obj;     
String name2 = s2.name;     
int rollno2 = s2.rollno;    
if(name1.equals(name2) && rollno1 == rollno2){   
return true;}   
else{     
return false;}  
}        
}