Collections HashSet verständnisproblem

Marc T.

Bekanntes Mitglied
Guten Tag,

ich war bisher der Annahme, dass beim Aufruf der Methode
Java:
java.util.HashSet.add(Object obj)
Der Hashwert des objekts mittels der Methode
Java:
public int hashCode()
ermittelt und mit den bereits vorhandenen werten des HashSets verglichen wird.

Ich habe hierzu folgende Testklasse implementiert:

Java:
public class Test {
	/**
	 * 
	 */
	private Set<String> words = null;
	
	/**
	 * 
	 * @param word
	 */
	public Test(Set<String> words) {
		this.words = words;
	}

	@Override
	public int hashCode() {
		int hash = 5;
		
		hash = 89 * hash + this.words.hashCode();
		
		return hash;
	}

	@Override
	public String toString() {
		String result = "";
		
		result = result + words.toString();
		
		return result;
	}
}

Jetzt möchte ich zwei Instanzen der Klasse Test erzeugen und in
ein HashSet packen. Ich sorge dafür, dass beide Klassen die gleichen
Elemente in ihrer Collection stehen haben, der entstehende hashcode
also gleich sein müsste:

Java:
public class TestMain {

	public static void main(String[] args) {
		Set<String> temp = new HashSet<String>();
		
		temp.add("Das");
		temp.add("ist");
		temp.add("ein");
		temp.add("Test");
		
		Test test1 = new Test(temp);
		Test test2 = new Test(temp);

		System.out.println("Hashwert: " + test1.hashCode());
		System.out.println("Hashwert: " + test2.hashCode());

		Set<Test> testSet = new HashSet<Test>();
		
		testSet.add(test1);
		testSet.add(test2);
		
		for(Test test : testSet) {
			System.out.println(test);
		}
	}
}

Nun habe ich allerdings in meinem Set zwei mal das Test-Objekt
mit ein und dem selben hashcode drin stecken. Wo ist hier mein
Denkfehler bzw. wie sorge ich dafür, dass ein Objekt mit dem gleichen
Hashwert nicht nochmal in mein Set hinzugefügt wird?

Code:
Hashwert: 2877113
Hashwert: 2877113
[Test, Das, ein, ist]
[Test, Das, ein, ist]
 

VfL_Freak

Top Contributor
Moin,

Nun habe ich allerdings in meinem Set zwei mal das Test-Objekt mit ein und dem selben hashcode drin stecken. Wo ist hier mein Denkfehler bzw. wie sorge ich dafür, dass ein Objekt mit dem gleichen
Hashwert nicht nochmal in mein Set hinzugefügt wird?
Ich verstehe jetzt die Frage nicht wirklich ... der Code macht doch genau das was er soll :noe:
Du erzeugst ZWEI Objekte, gibst ZWEI Strings aus und fügst BEIDE dem hashSet hinzu ....

Gruß
Klaus
 

kaoZ

Top Contributor
Ich glaube es geht ihm eher darum das beide Objekte einen Identischen Hash haben , was aber klar ist da beide Objekte in dieser Methode

Java:
@Override
    public int hashCode() {
        int hash = 5;
        
        hash = 89 * hash + this.words.hashCode();
        
        return hash;
    }

eben einen Identischen Hash berechnen, der die Speicheradresse nicht mit einbezieht, wenn sich nun die variable word für jedes Objekt ändern würde würde auch ein unterschiedlicher Hashwert berechnet werden.
 
Zuletzt bearbeitet:

Marc T.

Bekanntes Mitglied
Nein nein, das ist nicht das was ich meine. Ich möchte nicht,
dass das Objekt ein zweites mal dem Set hinzugefügt wird,
wenn der Hashwert der gleiche ist. Ich dachte das wäre der
Sinn eines HashSets, dass jedes Objekt, identifiziert durch seinen
hashwert, nur genau einmal im Set vorhanden sein darf.
 
Zuletzt bearbeitet:

kaoZ

Top Contributor
Ich möchte nicht,
dass das Objekt ein zweites mal dem Set hinzugefügt wird,

Das ist der Sinn des HashSet's :)

Schau dir mal die implementierung dahinter an wenn du Objekte zum Set hinzufügst, das Set verwendet eine HashMap für dessen Datenspeicherung , du musst also eigentlich wenn du die
Code:
hashCode()
überschreibst auch
Code:
equals()
überschieben

Java:
private static final Object PRESENT = new Object();

 public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }

Du überschreibst zwar hashCode , dieser wird aber in der Standardimplementierung von equals(); nicht mit einbezogen!
 
Zuletzt bearbeitet:

kaoZ

Top Contributor
Was ergibt wird den ausgegeben wenn du deine Testobjekte mal mit
Code:
==
vergleichts, ich vermute mal false oder ?

Hier nochmal im Detail :

Adds the specified element to this set if it is not already present. More formally, adds the specified element e to this set if this set contains no element e2 such that (e==null ? e2==null : e.equals(e2)). If this set already contains the element, the call leaves the set unchanged and returns false.

Specified by: add(...) in Set, Overrides: add(...) in AbstractCollection
Parameters:
e element to be added to this set
Returns:
true if this set did not already contain the specified element

Das hier ist relevant :

Java:
(e==null ? e2==null : e.equals(e2))
 
Zuletzt bearbeitet:

Marc T.

Bekanntes Mitglied
Achso, also ist es dem HashSet völlig egal was im hashcode() steht.
Die interessante Methode ist equals. Okay. Dann pack ich in die equals
einfach rein ob der hashcode gleich ist dann müsste ich das haben was
ich möchte.
 

kaoZ

Top Contributor
Hier mal ein Beispiel

Java:
public class Foo{
	
	public Foo() {}
	
	class Test{
		String s;
		
		public Test(String s){
			this.s = s;
		}
		
		@Override
		public int hashCode(){
			return 13;
		}
		
		@Override
		public boolean equals(Object o){
			if (this == o) {
	            return true;
            }
			return false;
		}
		
		public String getString() 			{return this.s;}
		
	}
	
	public static void main(String[] args) {
	 
		HashSet<Object> set = new HashSet<>();
		
		Test one = new Foo().new Test("Hallo");
		Test two = new Foo().new Test("Hallo");
		
		System.out.println(one.hashCode());
		System.out.println(two.hashCode());
		
		System.out.println(one.equals(two));
		System.out.println(one == two);
		System.out.println(one.getString().equals(two.getString()));
		
		System.out.println(set.add(one));  // wird hinzugefügt !
		
		
		System.out.println(set.add(one));  // wird NICHT hinzugefügt weil bereits vorhanden !
		System.out.println(set.size());

    }
}

Ausgabe ist :

13
13
false
false
true
false
1

Wie du deutlich sehen kannst sind Objekt one und two obwohl sie den gleichen Hashwert besitzen nicht identisch, hier ist wichtig zu wissen das gleich und identisch verschiedene definitionen besitzen,

nur weil zwei Objekte identisch sind , sind diese noch lange nicht Gleich !

die Methode set(Objekt o) liefert einen boolschen wert, der dafür steht ob ein Objekt hinzugefügt wurde oder nicht

in unserem Fall versuchen wir 2 mal das gleiche Objekt hinzuzufügen, bedeutet der die erste ausgabe liefert true , das Objekt wird hinzugefügt und die zweite liefert false, da dieses Objekt bereits im Set vorhanden ist

Obwohl nun Objekt one und Objekt two inhaltlich identisch sind, sind es dennoch verschiedene Objekte, ein Referenzvergleich mittels
Code:
==
liefert demnach hierfür false!

anders wenn wir nun folgendes machen würden :

Java:
Test one = new Foo().new Test("Hallo");
Test two = one;

nun Referenziert Objekt two Objekt one , verweist also auf das gleiche Objekt und somit auch auf die gleiche Speicheradressierung, demnach liefert jetzt ein Referenzvergleich mittels
Code:
==
nun
Code:
true
.

Hoffe es war halbwegs übersichtlich , wenn du noch Fragen haben solltest immer raus damit :)
 
Zuletzt bearbeitet:

Marc T.

Bekanntes Mitglied
Ja, um die von mir gewünschte Funktionalität zu bekommen also einfach:

Java:
public class Test {
    /**
     * 
     */
    private Set<String> words = null;
    
    /**
     * 
     * @param word
     */
    public Test(Set<String> words) {
        this.words = words;
    }
	
	@Override
	public boolean equals(Object o) {
		return this.hashCode() == o.hashCode();
	}
 
    @Override
    public int hashCode() {
        int hash = 5;
        
        hash = 89 * hash + this.words.hashCode();
        
        return hash;
    }
 
    @Override
    public String toString() {
        String result = "";
        
        result = result + words.toString();
        
        return result;
    }
}

Und es funktioniert. Danke.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
J HashSet mit Comparable sortieren Java Basics - Anfänger-Themen 13
berserkerdq2 Geht collections.sort bei allen? Linkedhashset, ArrayList, HashSet etc. Java Basics - Anfänger-Themen 4
volcanos HashSet und Iterator -> Falsche Sortierreihenfolge ? Java Basics - Anfänger-Themen 18
D Erste Schritte Code verstehen - HashSet Java Basics - Anfänger-Themen 8
J Hashset Java Basics - Anfänger-Themen 13
J HashSet Methode contains liefert false (hash Methode überschrieben) Java Basics - Anfänger-Themen 3
W Element aus HashSet in String umformen Java Basics - Anfänger-Themen 7
T HashSet in List-Object Java Basics - Anfänger-Themen 5
C Auf einzelne Werte aus HashSet zugreifen Java Basics - Anfänger-Themen 10
J Klassen HashSet, TreeSet: unregelmäßige Zahlenreihen beim Befüllen Java Basics - Anfänger-Themen 7
T Methoden HashSet Objekt mit Zufallszahlen befüllen Java Basics - Anfänger-Themen 3
J Verstehe meine HashSet Ausgabe nicht Java Basics - Anfänger-Themen 5
W Verknüpfung von Räumen mit Hashset Java Basics - Anfänger-Themen 10
J HashSet contain Methode funktioniert nicht wie gewollt Java Basics - Anfänger-Themen 7
R Hashset.add(Array) liefert immer true? Java Basics - Anfänger-Themen 23
Mrtwomoon Collections Hashset elemente ohne Eckigeklammer ausgeben Java Basics - Anfänger-Themen 9
M Collections Problem bei Überschreibung von hashcode() und equals() bei Hashset-Implementierung Java Basics - Anfänger-Themen 5
A Elemente in HashSet enthalten oder nicht Java Basics - Anfänger-Themen 6
A HashSet (oder besser geignetes) Java Basics - Anfänger-Themen 14
T Hashset - Allgemeine Fragen Java Basics - Anfänger-Themen 19
J So ähnlich wie HashSet Java Basics - Anfänger-Themen 2
D HashSet vs Liste Java Basics - Anfänger-Themen 5
T HashSet Java Basics - Anfänger-Themen 3
F suche Elemente in HashSet Java Basics - Anfänger-Themen 5
E Collections HashSet - Ausgabe sortiert? Java Basics - Anfänger-Themen 3
J HashSet Fehlerhaft Java Basics - Anfänger-Themen 10
J HashSet Implementierung Java Basics - Anfänger-Themen 16
D Problem mit HashSet Java Basics - Anfänger-Themen 12
darekkay Datentypen HashSet bzw. LinkedList mit Werten initialisieren Java Basics - Anfänger-Themen 3
B Hashset iterieren problem Java Basics - Anfänger-Themen 3
C HashSet Problem Java Basics - Anfänger-Themen 3
DasBrot Datentypen HashSet contains() Java Basics - Anfänger-Themen 3
F HashSet u. LinkedHashSet Zugriff auf Werte? Java Basics - Anfänger-Themen 2
F HashSet und LinkedHashSet Instanzierung warum so? Java Basics - Anfänger-Themen 7
M HashSet.contains() Java Basics - Anfänger-Themen 2
N Map<String, HashSet<String>> Umwandeln in Map<String, ArrayList<String>> Java Basics - Anfänger-Themen 14
neurox Limit bei HashSet? Java Basics - Anfänger-Themen 2
Povlsen84 HashSet mit eigenen Datentypen Java Basics - Anfänger-Themen 6
G HashSet vs. TreeSet Java Basics - Anfänger-Themen 3
G hashset überschreibt werte bei add Java Basics - Anfänger-Themen 1
G Wie mach ich ein HashSet für eigene Objecte? Java Basics - Anfänger-Themen 9
M HashSet Initialisierungsgröße? Java Basics - Anfänger-Themen 5
F doppelte Elemente in HashSet Java Basics - Anfänger-Themen 5
G Probleme mit HashSet Java Basics - Anfänger-Themen 5
S HashSet in HashMap, Zugriff Java Basics - Anfänger-Themen 3
G Zahlen aus HashSet in ein int Array übergeben Java Basics - Anfänger-Themen 15
G Hashset verknüpfen mit BufferedReader Java Basics - Anfänger-Themen 18
L Was ist ein HashSet? Java Basics - Anfänger-Themen 33
G HashSet Java Basics - Anfänger-Themen 21
P HashSet und Referenzen Java Basics - Anfänger-Themen 9
B Warum hat HashSet kein get(Object o) ? Java Basics - Anfänger-Themen 8
H umwandeln zu Hashset ?! Java Basics - Anfänger-Themen 7
K Verständnisproblem bei Server/Client Java Basics - Anfänger-Themen 3
nonickatall Grundsätzliches Verständnisproblem des Aufbaus eines Programms Java Basics - Anfänger-Themen 19
X Verständnisproblem Call-By-Reference Java Basics - Anfänger-Themen 5
P JavaFX: Verständnisproblem bei ComboBox/ChoiceBox etc. Java Basics - Anfänger-Themen 9
T Verständnisproblem mit Assoziationen Java Basics - Anfänger-Themen 7
M Verständnisproblem der Rekursion bei Arrays Java Basics - Anfänger-Themen 8
A Erste Schritte Verständnisproblem Java Basics - Anfänger-Themen 5
S Verständnisproblem Aufgabe Java Basics - Anfänger-Themen 9
S Model View Controller: Verständnisproblem Java Basics - Anfänger-Themen 13
temi Verständnisproblem Class.forName() Java Basics - Anfänger-Themen 3
2 Verständnisproblem bei Anwendung von Lower Bounded Wildcards Java Basics - Anfänger-Themen 5
V Verständnisproblem Java Basics - Anfänger-Themen 22
L [Verständnisproblem] Array wird trotz void rückgabe verändert. Java Basics - Anfänger-Themen 5
A Verständnisproblem Ausgabe Do-While-Schleife Java Basics - Anfänger-Themen 3
J Verständnisproblem einer Methode Java Basics - Anfänger-Themen 20
M Konstruktur - Verständnisproblem Java Basics - Anfänger-Themen 4
C Postinkrement und println - Verständnisproblem Java Basics - Anfänger-Themen 8
T Verständnisproblem beim Vigenere-Verfahren Java Basics - Anfänger-Themen 2
Q MVC Verständnisproblem: Controller vs model.modelChanged() Java Basics - Anfänger-Themen 0
N Verständnisproblem InsertionSort. Java Basics - Anfänger-Themen 2
D Verständnisproblem Java Basics - Anfänger-Themen 2
B VerständnisProblem mit Beispielaufgabe aus Buch Java Basics - Anfänger-Themen 1
H Polymorphie Verständnisproblem Vererbung/Polymorphie Java Basics - Anfänger-Themen 4
FrankR2 Grundsätzliches Verständnisproblem: Java 32/64-bit; Windows 7/8, 32/64-bit-System Java Basics - Anfänger-Themen 5
S Verständnisproblem bei Interfaces Java Basics - Anfänger-Themen 6
V Verständnisproblem Java Basics - Anfänger-Themen 5
V Arrays-verständnisproblem Java Basics - Anfänger-Themen 4
S Verständnisproblem einer Übungsaufgabe Java Basics - Anfänger-Themen 6
H Abstrakte Basisklasse Verständnisproblem! Java Basics - Anfänger-Themen 8
G Verständnisproblem mit swing Java Basics - Anfänger-Themen 6
F Methoden Cannot refer to a non-final variable.. verständnisproblem. Java Basics - Anfänger-Themen 7
P Verständnisproblem main Methode Java Basics - Anfänger-Themen 9
S Klassen Verständnisproblem Konstruktor Java Basics - Anfänger-Themen 7
I e.getMessage(); - Verständnisproblem Java Basics - Anfänger-Themen 6
lesni Vererbung Vererbung - Verständnisproblem Java Basics - Anfänger-Themen 2
M OOP Polymorphie/Vererbung Verständnisproblem Java Basics - Anfänger-Themen 2
J Verständnisproblem Methoden-Kettung Java Basics - Anfänger-Themen 3
A Vererbung Verständnisproblem bei Übung Java Basics - Anfänger-Themen 5
E Verständnisproblem Typkonvertierung Java Basics - Anfänger-Themen 4
S OOP Verständnisproblem Umsteiger Java Basics - Anfänger-Themen 22
C Array Verständnisproblem Java Basics - Anfänger-Themen 3
P White-Box-Test Verständnisproblem Java Basics - Anfänger-Themen 11
D : ? Operator -Verständnisproblem Java Basics - Anfänger-Themen 24
G Verständnisproblem: Exceptions Java Basics - Anfänger-Themen 17
L Eclipse verlangt "{" nach ";"... Verständnisproblem Java Basics - Anfänger-Themen 5
D charAt(i) verständnisproblem Java Basics - Anfänger-Themen 4
D Verständnisproblem Marken und Schleifen Java Basics - Anfänger-Themen 19
M Verständnisproblem bei Ternären Operanten bzw. Bedingungsoperator Java Basics - Anfänger-Themen 8

Ähnliche Java Themen

Neue Themen


Oben