"java suck"
-
Heinzelotto schrieb:
Two identical byte[] arrays aren't equal and don't hash the same. Maybe this is just a bug, but:
You can't fix this by subclassing Hashtable.
You can't fix this by subclassing Array because it's not really an object. What you can do is wrap an Object around an Array and let that implement hashCode and equals by digging around in its contained array, but that adds not-insignificant memory overhead (16 bytes per object, today.)
Gee, I know, I'll write my own hash table. I've only done that a thousand times.
musste ich heute selbst wieder an eigener Haut erfahren.
Die Lösung ist recht simpel (Arrays.equals(array1, array2)) und existiert seit Version 1.2, also seit rund 11 Jahren.
-
byto schrieb:
Die Lösung ist recht simpel (Arrays.equals(array1, array2)) und existiert seit Version 1.2, also seit rund 11 Jahren.
Das Problem ist nicht 2 Zeichenketten auf gleichheit zu überprüfen sondern den hash einer bytefolge zu nehmen.
habe ich persönlich nie gebraucht, aber wenn 2 identische bytearrays unterschiedlichen hash code liefern, ist das ein fehler.
-
Mit Operatorenüberladung wär das nicht passiert!
-
Shade Of Mine schrieb:
habe ich persönlich nie gebraucht, aber wenn 2 identische bytearrays unterschiedlichen hash code liefern, ist das ein fehler.
das ist kein fehler. der hashcode bezieht sich auf die objekte, nicht deren inhalt.
// hashcodes von a und c sind gleich, b ist unterschiedlich byte[] a = {1,2,3,4,5}; byte[] b = {1,2,3,4,5}; byte[] c = a;
-
~fricky schrieb:
das ist kein fehler. der hashcode bezieht sich auf die objekte, nicht deren inhalt.
in der tat.
das macht hashCode für arrays natürlich ziemlich nutzlos - aber wenn es so definiert wurde... tja, dann kann man nichts machen.IMHO auch eine sehr fragwürdige definition von equals - denn für identity ist eigentlich == zuständig...
-
Doch, da kann man was machen: Arrays.hashcode(array)
Hilft natürlich wenig, wenn man Arrays z.B. in HashSets schmeissen will, macht aber eh kein normaler Mensch, von daher.
Jeder vernünftig denkende Mensch programmiert nach den Interfaces der Collection API und verwendet (bei Bedarf) ArrayList statt Arrays.
-
Shade Of Mine schrieb:
~fricky schrieb:
das ist kein fehler. der hashcode bezieht sich auf die objekte, nicht deren inhalt.
in der tat.
bei strings könnte man meinen, es wäre anders. das liegt aber nur daran, dass strings unveränderlich sind und daher dürfen alle strings mit gleichem inhalt auch das gleiche objekt sein. beispiel:
String a = "hallo"; String b = "hallo"; String c = a; String d = a.substring(0);
^^ sieht nach 3 oder 4 verschiedenen objekten aus. tatsächlich gibt es "hallo" aber nur ein mal.
-
~fricky schrieb:
Shade Of Mine schrieb:
~fricky schrieb:
das ist kein fehler. der hashcode bezieht sich auf die objekte, nicht deren inhalt.
in der tat.
bei strings könnte man meinen, es wäre anders. das liegt aber nur daran, dass strings unveränderlich sind und daher dürfen alle strings mit gleichem inhalt auch das gleiche objekt sein. beispiel:
String a = "hallo"; String b = "hallo"; String c = a; String d = a.substring(0);
^^ sieht nach 3 oder 4 verschiedenen objekten aus. tatsächlich gibt es "hallo" aber nur ein mal.
Lol? Und dann über C++ lästern
Wie sinnvoll ist es denn bitte Objekte nach Identität und nicht nach Gleichheit zu hashen?
-
C++-Progger schrieb:
Wie sinnvoll ist es denn bitte Objekte nach Identität und nicht nach Gleichheit zu hashen?
sehr sinnvoll. kommt so ein objekt z.b. über eine netzwerkverbindung angeflogen, kannste es sofort identifizieren. seine daten, sein innerer zustand etc. sind dafür erstmal zweitrangig. was bedeutet für dich eigentlich 'gleichheit'?
C++-Progger schrieb:
Lol? Und dann über C++ lästern
das lass mal bleiben. hier ist doch der java-lästerthread.
-
C++-Progger schrieb:
Wie sinnvoll ist es denn bitte Objekte nach Identität und nicht nach Gleichheit zu hashen?
Objekte werden in Java nach Gleichheit gehasht. Aber der Hash von Arrays geht halt per Default nicht auf die Elemente. Anders ist das bei Collections (List, Set, Map). Der Hash von Arrays ist aber trotzdem konsistent mit der Gleichheit von Arrays, denn equals() geht auch hier nicht auf die Elemente. Möchte man dieses Verhalten für Arrays haben, dann benutzt man Arrays.equals(array1, array2) bzw. Arrays.hashcode(array1, array2). Oder man programmiert nach Schnittstellen und nimmt gleich ne (Array)List. Dann hat man Gleichheit / Hashcode auf den Elementen + Array Realisierung.
-
Shade Of Mine schrieb:
byto schrieb:
Die Lösung ist recht simpel (Arrays.equals(array1, array2)) und existiert seit Version 1.2, also seit rund 11 Jahren.
Das Problem ist nicht 2 Zeichenketten auf gleichheit zu überprüfen sondern den hash einer bytefolge zu nehmen.
habe ich persönlich nie gebraucht, aber wenn 2 identische bytearrays unterschiedlichen hash code liefern, ist das ein fehler.
Was hinder dich daran sowas zu schreiben:
class ArrayContainer { private byte[] bytes; public ArrayContainer(byte[] bytes) { ... } public int hashCode() { return Arrays.hashcode(bytes); } public boolean equals(Object that) {return Arrays.equals(that); } }
Und dann ArrayContainer anstatt dem Array in deine HashMap aufzunehmen? In dem Artikel wird zwar das Ableiten von Hashtable, Ableiten von Array und das Schreiben einer eigener HashMap vorgeschlagen, aber sowas einfach wie das Kapseln von Array wird natuerlich nicht erwaehnt.
Der ganze Artikel ist einfach Bloedsinn. Der Author ist bestimmt ein C/C++ Programmierer und erwartet das alle Sprachen sich wie diese verhalten muessen. Das faengt ja schon mit dem ersten Punkt an
It's hard to live with none of: lexically scoped local functions; a macro system; and inlined functions.
-
dafür, dass java so schlecht ist, ist es viel zu weit verbreitet
-
looooooooool schrieb:
dafür, dass java so schlecht ist, ist es viel zu weit verbreitet
ist doch mit vielen dingen so. suboptimales zeug stirbt nicht einfach aus, weil es besseres gibt. gerade bei programmiersprachen scheint's sowas wie 'natürliche selektion' nicht zu geben.
btw, ^^das soll nicht gegen java gerichtet sein. ich mag java ganz gern.
-
~fricky schrieb:
looooooooool schrieb:
dafür, dass java so schlecht ist, ist es viel zu weit verbreitet
ist doch mit vielen dingen so. suboptimales zeug stirbt nicht einfach aus, weil es besseres gibt. gerade bei programmiersprachen scheint's sowas wie 'natürliche selektion' nicht zu geben.
btw, ^^das soll nicht gegen java gerichtet sein. ich mag java ganz gern.
...du magst auch C ganz gern!
-
Ja aber... schrieb:
du magst auch C ganz gern
eigentlich schon. ist doch kein widerspruch, oder?
-
Doch :p
-
byto schrieb:
C++-Progger schrieb:
Wie sinnvoll ist es denn bitte Objekte nach Identität und nicht nach Gleichheit zu hashen?
Objekte werden in Java nach Gleichheit gehasht. Aber der Hash von Arrays geht halt per Default nicht auf die Elemente.
Per default wird nach Object.hashCode() gehasht und das macht es, wenn man es nicht überschreibt, für die Identität. Ebenso wie equals(). Egal ob für array oder nicht array, da gibt es keinen Unterschied. Überhaupt arbeiten diese beiden Methoden zusammen und man sollte entweder keine oder beide redefinieren.
@C++-Progger: Das ist nützlich, wenn es darum geht, genau das selbe Objekt schnell wieder zu finden und entspricht in etwa einem hashen nach Adresse. Die Nützlichkeit davon steht wohl außer Frage.
In den Collections kann man meines Wissens nach ggf. einen anderen Functor verwenden, wenn man nicht an der Identität interessiert ist. Das finde ich sauberer, als die Methoden von Object zu überschreiben, so schön wie boost.unordered macht es die Sache aber schon nicht.
-
~fricky schrieb:
looooooooool schrieb:
dafür, dass java so schlecht ist, ist es viel zu weit verbreitet
ist doch mit vielen dingen so. suboptimales zeug stirbt nicht einfach aus, weil es besseres gibt. gerade bei programmiersprachen scheint's sowas wie 'natürliche selektion' nicht zu geben.
Doch doch. Diese Selektion gibt es durchaus. Aber anscheinend ist es gerade bei Programmiersprachen so, dass vielen Leuten die Bewertungskriterien nicht klar sind. Da fokussiert man sich auf irgendwelche kleinen Sprachdetails und meint, daraus herleiten zu können, dass eine Sprache gegenüber einer anderen irgendwie minderwertig ist. Aber letztendlich spielen derartige Details ungefähr gar keine Rolle. Was zählt, ist ein Gesamtpaket, zu dem sogar noch wesentlich mehr als die Sprache ansich gehört.
-
Gregor schrieb:
~fricky schrieb:
looooooooool schrieb:
dafür, dass java so schlecht ist, ist es viel zu weit verbreitet
ist doch mit vielen dingen so. suboptimales zeug stirbt nicht einfach aus, weil es besseres gibt. gerade bei programmiersprachen scheint's sowas wie 'natürliche selektion' nicht zu geben.
Doch doch. Diese Selektion gibt es durchaus. Aber anscheinend ist es gerade bei Programmiersprachen so, dass vielen Leuten die Bewertungskriterien nicht klar sind. Da fokussiert man sich auf irgendwelche kleinen Sprachdetails und meint, daraus herleiten zu können, dass eine Sprache gegenüber einer anderen irgendwie minderwertig ist. Aber letztendlich spielen derartige Details ungefähr gar keine Rolle. Was zählt, ist ein Gesamtpaket, zu dem sogar noch wesentlich mehr als die Sprache ansich gehört.
Mir gefaellt an Java vor das Gesamtpaket, vor allem aber die Sprache an sich, das Konzept dahinter, die IDE und die Bibliothek. Die Build-Tools sind leider alle noch etwas Beta, zumindest Maven2. Es ist auf jeden fall ein gewaltiger Vortschritt im Gegensatz zu C oder C++.
-
DEvent schrieb:
Vortschritt
EPIC FAIL :p
java noob