Hashset.add(Array) liefert immer true?

Roccosi7

Mitglied
Hey,
Ich möchte aus einem String ein Byte-Array machen und dieses dann in ein Hashset schreiben.
Jedoch schreibt die Methode add auch schon vorhandene Byte-Arrays in das Hashset.

z.B.

Java:
byte[] bytes1 = "abc".getBytes("UTF-8");
byte[] bytes2 = "abc".getBytes("UTF-8");

boolean add1 = hashset.add(bytes1);
boolean add2 = hashset.add(bytes2);

schreibt beide Arrays in das Set, beiden booleschen Ausdrücke sind true.
Wie kann ich das verhindern?

Lg
 
T

tröööt

Gast
du kannst dir ja mal ausgeben lassen was "bytes1==bytes2" ausgibt ... ich vermute FALSE ... da beide arrays nicht gleich sein dürften ...

auch wenn "abc" im stringpool gecached wird wird in "getBytes()" jeweils ein neues array erzeugt ... und da sich arrays in java eher wie objekte anstatt wie primtives verhalten dürften die beiden arrays eine unterschiedlichen hash-liefern ... was dazu führt das beide eingefügt werden ... weil beides eben "verschiedene objekte" sind ...
 
N

nillehammer

Gast
Nein lieber nicht. Sets sorgen schon sehr gut dafür, dass keine Duplikate vorkommen. Duplikat heißt übrigens das equals() true liefert. Und das tut es bei Arrays eben nur, wenn die identisch sind. Insofern sind Arrays ungeeignet, um sie in einem Set zu speichern. Weiche darum auf List aus.
Helfen kann dabei folgende Methde aus der Api:
Java:
Arrays.asList(...);
Und wenn Du doch mit Array-Vergleichen rumbasteln willst/musst, ist die Methode hier noch hilfreich:
Java:
Arrays.equals(a, a2);
Die macht das, was man gerne hätte, nämlich testen, ob die Elemente der Arrays gleich sind.
 
Zuletzt bearbeitet von einem Moderator:
T

tröööt

Gast
naja ... da "byte1==byte2" FALSE ist wird wohl Collection.contains() auch FALSE liefern ...

man könnte jetzt entsprechend des ziel-types n bissl was schreiben was durch die liste geht ... den inhalt liest und prüft ob der parameter den man adden will mit irgendeinem wert der schon drin ist gleich ist ...

für arrays gibt es "Arrays.equals(T[])" ... ansonsten einfach Object.equals(Object) ...

problem ist halt das die beiden byte-arrays nicht ein und das gleich byte-array sind sondern zwei eigenständige ... und damit halt zwei unterschiedliche objekte ... das java nicht in der lage ist hier automatisch "Arrays.equals" zu callen erstaunt mich allerdings auch etwas
 
N

nillehammer

Gast
Was mich irritiert ist, dass bei arrays von primitives kein irgendwie geartetes Autoboxing stattfindet wenn es in ein HashSet geschickt wird. Jedenfalls gibt das .class-File nichts davon her. Verwurschtelt die Runtime das nativ?
Nein, es wird as Array als Objekt reingesteckt. Da muss nichts geboxed/geunboxed werden.
Das erkennt man ganz gut bei der generischen Definition des Sets:
Java:
// nicht sehr sinnvoll:
Set<int[]> intArraySet;
 
Zuletzt bearbeitet von einem Moderator:
N

nillehammer

Gast
Wo haste das Set<int[]>... gefunden? Mein Source von 1.6 gibt fürs Interface von Set nichts dergleichen her.
Meinst du mit Source den Quellcode des JDK? Da steht ja eh nicht viel Code drinnen, weils ein Interface ist. Ich habe das jedenfalls in einem anderen Zusammenhang mal ausprobiert (nicht mit Set, sondern List, aber ist ja im Prinzip egal). Ich hab hier leider nur eine 7er-Installation, aber, wenn ich in Eclipse das Compliance-Level auf 1.5 zurück stelle, meckert er auch nicht. Ich denke also, das geht, seit es Generics gibt.

P.S. Drauf gekommen bin ich, weil es auch sowas hier gibt:
Code:
int[].class
. Und da dachte ich, alles was eine Klasse ist, kann doch bestimmt auch ein generischer Parameter werden.
 
Zuletzt bearbeitet von einem Moderator:

Bernd Hohmann

Top Contributor
Stimmt. Primitive Arrays haben .class und auch .hashcode() - wobei letzterer nix bringt weil für gleiche Inhalte unterschiedliche Hashcodes erzeugt werden.

Naja, keine Sprache ist vollkommen.

Bernd
 

Timothy Truckle

Top Contributor
Hey,
Ich möchte aus einem String ein Byte-Array machen und dieses dann in ein Hashset schreiben.
Jedoch schreibt die Methode add auch schon vorhandene Byte-Arrays in das Hashset. z.B.
Java:
byte[] bytes1 = "abc".getBytes("UTF-8");
byte[] bytes2 = "abc".getBytes("UTF-8");

boolean add1 = hashset.add(bytes1);
boolean add2 = hashset.add(bytes2);
Ich bin ja immer wieder beeindruckt, mit welcher Energie die Leute versuchen, unlesbaren Code zu erzeugen.:rolleyes:

Wenn Du einfach die Strings in die Liste geworfen hättest, wäre da kein Problem...

bye
TT
 
N

nillehammer

Gast
Hab gerade gelesen das bei Listen die Methode contains() .equals für den Vergleich nutzt...das müsste bei zwei Inhaltlich gleichen Objekten doch true liefern oder nicht?
Nein! Das hatten trööt und ich schon in unseren ersten Antworten geschrieben, dass equals() bei Array-Objetken eben nicht auf Elementgleichheit prüft, sondern nur true zurück gibt, wenn sie identisch sind.

Es ist tatsächlich nur dann so, dass equals auf Inhalsgleichheit prüft, wenn der Autor der Klasse es entsprechend implementiert hat. Ansonsten wird immer nur bei Identität true zurück gegeben.

P.S. Und übrigens unter der Haube prüft Set.add() auch per equals (zumindest bei den usortierten Varianten wie HashSet).
 
Zuletzt bearbeitet von einem Moderator:
N

nillehammer

Gast
[OT]
Stimmt. Primitive Arrays haben .class und auch .hashcode() - wobei letzterer nix bringt weil für gleiche Inhalte unterschiedliche Hashcodes erzeugt werden.

Naja, keine Sprache ist vollkommen.
Ja, ich glaube, das ist Teil des Murkses, dass in der OO-Sprache Java Nicht-Objekte (also die Primitiven) vorkommen. In "echten" OO-Sprachen stellt sich das Problem ja so überhaupt nicht.
[/OT]
 

Bernd Hohmann

Top Contributor
Hab gerade gelesen das bei Listen die Methode contains() .equals für den Vergleich nutzt...das müsste bei zwei Inhaltlich gleichen Objekten doch true liefern oder nicht?

Jein.

Arrays von primitiven Datentypen werden als java.lang.Object gespeichert und das dort implementierte .equals prüft nur ob die Objektreferenzen identisch sind. In Deinem Fall werden (trotz identischem Inhalt) zwei unterschiedliche Objekte erzeugt die demnach nicht die gleiche Objektreferenz haben.

Wenn man Objekte auf inhaltliche Gleichheit prüfen möchte, muss man .equals überschreiben und das darin entsprechend Programmieren. Typischer Fall ist zb. die Klasse String wo im .equals(...) tatsächlich Zeichenweise abgeglichen wird.

Was Du machen kannst, ist einen Wrapper für Deine bytearrays zu schreiben wo das .equals(...) die arrays auf Inhalt vergleicht.

Bernd
 
N

nillehammer

Gast
Bernd hat gesagt.:
Was Du machen kannst, ist einen Wrapper für Deine bytearrays zu schreiben wo das .equals(...) die arrays auf Inhalt vergleicht.
War auch eine meiner ersten Ideen. Aber dann müssten equals und hashCode in der Wrapperklasse überschrieben werden. Das ist unnötige Arbeit, wenn man mit Arrays.asList() genau so einen "Wrapper" bereits frei Haus bekommt. Und das Speichern von Arrays gilt für alle Elementtypen. Zwei nicht-identische Arrays sind nie equal auch nicht, wenn dort echte Objekte drinnen sind. Zum Test folgender Code:
Java:
    String[] strArr1 = {"1", "2"};
    
    String[] strArr2 = {"1", "2"};
    
    System.out.println(strArr1.equals(strArr2));
 
Zuletzt bearbeitet von einem Moderator:

Roccosi7

Mitglied
Oh Gott ich will die ganze zeit antworten, komm aber nie dazu weil immer schonwieder jemand anderes geantwortet hat. Gefällt mir ;)

Das ganze hat sich aber, denke ich, schon erledigt; Ich habe das ganze grade mal mit "gewrapten" BufferedBytes ausprobiert und das ist noch langsamer und Speicherintensiver als gleich den String als ganzes zu nehmen.

Danke & Lg
 

Bernd Hohmann

Top Contributor
War auch eine meiner ersten Ideen. Aber dann müssten equals und hashCode in der Wrapperklasse überschrieben werden. Das ist unnötige Arbeit, wenn man mit Arrays.asList() genau so einen "Wrapper" bereits frei Haus bekommt.

Anscheinend nicht. Bei mir (Java 1.6) liefert auch Arrays.asList(...) nur eine Liste mit 1 Objekt zurück und .equals() darauf vergleicht dieses eine Objekt mit dem anderen aus der Liste via Object#equals(....).

Java:
import java.util.*;

public class Test {
	public static void main(String str[]) throws Throwable {
		HashSet hs = new HashSet();

		byte[] bytes1 = "abc".getBytes("UTF-8");
		byte[] bytes2 = "abc".getBytes("UTF-8");

		List l1 = Arrays.asList(bytes1);
		List l2 = Arrays.asList(bytes2);

		System.out.println(l1.size());
		System.out.println(l2.size());
		System.out.println(l1.equals(l2));

		boolean add1 = hs.add(bytes1);
		boolean add2 = hs.add(bytes2);
	}
}

Zum Glück traue ich keiner API die ich nicht selber geschrieben habe.

Bernd
 
N

nillehammer

Gast
Bernd Hohmann hat gesagt.:
Anscheinend nicht. Bei mir (Java 1.6) liefert auch Arrays.asList(...) nur eine Liste mit 1 Objekt zurück und .equals() darauf vergleicht dieses eine Objekt mit dem anderen aus der Liste via Object#equals(....).
Oha, da hast du mich jetzt erwischt! Ich habe das natürlich in anderen Zusamenhängen NICHT mit primitiven Arrays probiert. Der varargs-Parameter erwartet ja Objekte. Während man also einen Array von Objekten übergeben kann und die varargs-Methode das dann in die Elemente aufdröselt, tut sie das bei Primitiven-Arrays natürlich nicht, sondern nimmt das Array als einziges Objekt. Jetz weiß ich auch, was du weiter vorne mit Autoboxing meintest! Touché Herr Hohmann!
 
T

tröööt

Gast
da ist man mal einen abend nicht da und hier läuft in 2h die schönste diskusion über arrays ...

ob nun arrays intern wirklich als Object gespeichert werden weis ich nicht ... aber ihre verhalten "fühlt" sich dann doch eher wie ein objekt an anstatt wie mit einem haufen primitives ...
ich weis nicht ob das nur in java so ist oder auch andere sprachen betrifft ... und ich würde gerne mal eine sprache sehen in der es KEINE primitives gibt (wie hier genannt "echt-oop") ... fällt mir halt schwer das nach zu vollziehen ...

ich denke auf die idee am besten einfach die Strings ins HashSet stecken anstatt byte-arrays sind wir hier alle sofort gekommen ... und ich wollte auch eigentlich keine diskusion über arrays , primitives und ojects anfachen ... sondern TO lediglich sagen das "byte1" eben NICHT "==" bzw "equals()" "byte2" ist ... und desshalb die interne prüfung in add() nun mal korrekterweise zwei unterschiedliche objekte siehr und beide desshalb auch ins set packt ...

mehr wollte ich eigentlich nicht sagen und damit diese diskusion hier anzetteln ... wobei ichs auch informativ finde arrays mal so auseinander zu nehmen ...


@TO
was mich jetzt nur interessieren würde für welche lösung du dich jetzt entschieden hast ...
 

xehpuk

Top Contributor
Zum Glück traue ich keiner API die ich nicht selber geschrieben habe.
Das passiert nun mal, wenn man die API nicht richtig nutzt.

Da du ja Java 6 nutzt, wirst du sicherlich auch wissen, was Generics sind. [JAPI]List[/JAPI] ist generisch und [JAPI]Arrays#asList(T...)[/JAPI] auch.
Hier hätte es also einen Kompilierfehler gegeben:
Java:
List<Byte> l1 = Arrays.asList(bytes1);
// incompatible types
//   required: List<Byte>
//   found:    List<byte[]>
Man erfährt also, dass der Compiler
Code:
byte[]
statt
Code:
Byte
als
Code:
T
ansieht.
Hilft man ihm nun auf die Sprünge, erhält man einen anderen Kompilierfehler:
Java:
List<Byte> l1 = Arrays.<Byte>asList(bytes1);
// method asList in class Arrays cannot be applied to given types;
//   required: T[]
//   found: byte[]
//   reason: argument type byte[] does not conform to vararg element type Byte
//   where T is a type-variable:
//     T extends Object declared in method <T>asList(T...)
Man erfährt also schon beim Kompilieren, dass die API das nicht zulässt, nicht erst zur Laufzeit.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
G Zahlen aus HashSet in ein int Array übergeben Java Basics - Anfänger-Themen 15
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
M Collections HashSet verständnisproblem Java Basics - Anfänger-Themen 9
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 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
T Array verkleinern Java Basics - Anfänger-Themen 2
J Array aus Numberfield Eingaben Java Basics - Anfänger-Themen 7
D Array List mit Objekten sortieren Java Basics - Anfänger-Themen 2
onlyxlia Anzahl Random Zahlen mit Scanner abfragen und in Array speichern Java Basics - Anfänger-Themen 10
Ü Java Array - Buchstaben als Zahlen ausgeben Java Basics - Anfänger-Themen 22
Ü Zweidimensionales Array in der ersten Zeile deklarieren Java Basics - Anfänger-Themen 13
Thomas Uppe 2D Array Reihenfolge vermischen Java Basics - Anfänger-Themen 4
T array auslesen Java Basics - Anfänger-Themen 2
Nitrogames Variablen Variable aus JOptionPane Abfrage in Array einfügen Java Basics - Anfänger-Themen 4
moini Auf Array aus Superklasse zugreifen? Java Basics - Anfänger-Themen 2
J ArrayList in 2D-Array konvertieren. Java Basics - Anfänger-Themen 48
M NullPointerException: Cannot read the array length because "this.Kinder" is null Java Basics - Anfänger-Themen 1
P Wieso kann ich als Index für einen Array einen Char angeben? Java Basics - Anfänger-Themen 3
Finn_lol Fehlermeldung bei Schleife mit Array Java Basics - Anfänger-Themen 4
Proxy Chars vor array übergabe toLowerUpcase Java Basics - Anfänger-Themen 14
iAmFaiinez Primzahlen Tester ohne Array Java Basics - Anfänger-Themen 4
S array 2 dimensional treppe Java Basics - Anfänger-Themen 3
S Array 2x2 Blöcke mit 0 und 1 Java Basics - Anfänger-Themen 10
C Array von Klassen Java Basics - Anfänger-Themen 2
julian0507 2Dim-Array Spaltensummen Java Basics - Anfänger-Themen 1
XWing Doppelte Zahlen im Array Java Basics - Anfänger-Themen 8
melisax Java 2D-Array Tabelle Java Basics - Anfänger-Themen 4
melisax Java Array Wert an bestimmtem Index angeben Java Basics - Anfänger-Themen 14
W Items löschen aus String Array vom Custom Base Adapter Java Basics - Anfänger-Themen 2
Proxy Stack erweitern mit neuem Array falls der alte voll ist!? Java Basics - Anfänger-Themen 5
E Array, nächste Zahl zur 5 ausgeben, wie? Java Basics - Anfänger-Themen 42
J Array.list vergleichen Java Basics - Anfänger-Themen 1
W Java-Code mit Array Java Basics - Anfänger-Themen 14
D Reflections & Generisches Array Java Basics - Anfänger-Themen 4
T Array Java Basics - Anfänger-Themen 2
T Array Java Basics - Anfänger-Themen 15
T Wörteranzahl im Array zählen Java Basics - Anfänger-Themen 9
Ostkreuz Zweidimensionaler Array Index Java Basics - Anfänger-Themen 2
S String Array Buchstaben um einen gewissen Wert verschieben Java Basics - Anfänger-Themen 4
R Images aus einem Array ausgeben Java Basics - Anfänger-Themen 3
R 2d Array individuell machen Java Basics - Anfänger-Themen 4
D 2D Char Array into String Java Basics - Anfänger-Themen 2
J Array Median bestimmen Java Basics - Anfänger-Themen 6
S Array Maximum bestimmen mit for und foreach Java Basics - Anfänger-Themen 7
S Prüfen ob ein zweidimensionales Array rechteckig ist Java Basics - Anfänger-Themen 4
N Array Java Basics - Anfänger-Themen 1
J Array Mittleren Wert bestimmen Java Basics - Anfänger-Themen 2
D OOP Array einem Objekt zuweisen Java Basics - Anfänger-Themen 2
O Zahlen aus einem char-array per char + Zeichen addieren Java Basics - Anfänger-Themen 2
S leeres Array statt Null Pointer Exception ausgeben Java Basics - Anfänger-Themen 20
S Inhalte aus Array vergleichen und Max ausgeben Java Basics - Anfänger-Themen 3
M 2d array ohne längen anlegen Java Basics - Anfänger-Themen 4
S Bestimmte werte aus einem Array löschen Java Basics - Anfänger-Themen 2

Ähnliche Java Themen

Neue Themen


Oben