# Überschreiben von equals und hashcode für Collection



## vogella (17. Aug 2007)

Hallo,

ich habe equals und hashcode in meiner Klasse überschreiben und in einer Collection einfach überprüfen zu können, ob ein Element schon in der Liste existiert. Allerdings werden die überschriebenen Methoden von equals und hashcode von der contains Methode der Collection nicht aufgerufen.

Weißt jemand, was ich falsch mache?

Ein einfaches Beispiel anbei.

Klasse name. Diese Klasse überschreibt equals (und hashcode). D.h. zwei Object sollten meiner Meinung nach gleich sein, wenn sie den selben Namen haben. 

```
package testEquals;

public class Name {
    private String name;

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

    public String getName() {
	return name;
    }

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

    @Override
    public boolean equals(Object o) {
	System.out.println("Should be called!");
	if (o instanceof String) {
	    if (((String) o).equalsIgnoreCase(this.getName())) {
		return true;
	    }
	}
	return false;
    }

}
```

Test Program. Leider wird die equals methode von Name gar nicht aufgerufen, obwohl constains equals über die Method indexOf aufruft (im Java Standard Coding).




```
package testEquals;

import java.util.ArrayList;

public class Main {

    public static void main(String[] args) {
	ArrayList<Name> list = new ArrayList<Name>();
	Name person = new Name();
	person.setName("Lars");
	list.add(person);
	if (list.contains("Lars")) {
	    System.out.println("Super");
	} else
	    System.out.println("Schade");
    }
}
```

Viele Grüße, Lars


----------



## SlaterB (17. Aug 2007)

sehr wahrscheinlich wird die equals-Operation von "Lars" aufgerufen, von dem String,

und String.equals sagt: Name ist doof, bäh,


->
Suche mit einem neuen Name-Objekt mit dem Namen "Lars"


edit:


```
public int indexOf(Object elem) {
	if (elem == null) {
	    for (int i = 0; i < size; i++)
		if (elementData[i]==null)
		    return i;
	} else {
	    for (int i = 0; i < size; i++)
		if (----> elem.equals(elementData[i])  <-----)
		    return i;
	}
	return -1;
    }
```


----------



## Beni (17. Aug 2007)

"contains" ruft die equals-Methode von String auf (von dem Objekt, das der contains-Methode übergeben wurde).

Deine equals-Methode ist falsch implementiert. Ein String kann niemals dasselbe wie ein Name sein! Denn die Klassen müssen übereinstimmen. Schau mal in der API nach, wie die equals-Methode aussehen muss.


----------



## ms (17. Aug 2007)

vogella hat gesagt.:
			
		

> ```
> if (list.contains("Lars")) {
> System.out.println("Super");
> } else
> ...



Nicht nur die equals-Methode ist falsch, sondern auch dein Testprogramm.
Du müsstest der contains-Methode richtigerweise ein Objekt vom Typ Person übergeben.
Dann sollte zumindest die equals-Methode aufgerufen werden.

Edit: seh gerade, dass das eh schon erwähnt wurde.


----------



## Guest (17. Aug 2007)

Gleiche Objekte müssen den selben Hashcode haben. Zwei Personen namens "Lars" und "lars" werden von Dir als gleich angesehen, haben aber nicht den selben Hashcode!

Mein Vorschlag:


```
public int hashCode() {
	return name.hashCode();
    }

    public boolean equals(Object o) {
        return (o instanceof String) && ((String o).equals(name));
    }
}
```

Fred


----------



## SlaterB (17. Aug 2007)

oder Namen als toLowerCase() speichern + hashCode berechnen,

da andere Namen dann auch immer kleine Namen haben, könnte man wieder das normale equals nehmen,
oder den Namen normal speichern und nur für hashcode()-Berechnung toLowerCase()


----------



## Beni (17. Aug 2007)

> ```
> public boolean equals(Object o) {
> return (o instanceof String) && ((String o).equals(name));
> }
> ```


Nein


```
(o != null) &&
(o instanceof Name) &&
((o.name == null && name == null) || (o.name.equals( name )))
```


----------



## vogella (17. Aug 2007)

Hallo,

vielen Dank für die schnellen Antworten. Jetzt kann ich es korrekt anwenden. 

Viele Grüße, Lars


----------

