jmeMedlem sedan maj 20011 967 inlägg
Hej!
Just nu så har jag följande problem:
Jag använder mig utav en hashSet för att lagra objekt. Vad jag vet så kan inte en HashSet innehålla två identiska objekt, vilket är vad jag vill.
HashSet hash = new HashSet();
hash.add(new java.awt.Point( 10,10) );
hash.add(new java.awt.Point( 10,10) ); // försöker lagra en identisk obket i hash men dett fungerar inte, bra!
Låt oss säga att jag skapar en Operator klass med två instans variablar:
String name;
String password;
konstruktorn är:
new Operator(name, password);
om jag då försöker lagra en Operator i hash;
Operator op = new Operator("Kalle", "abc77");
hash.add(op):
hash.add(op);
nu så lagras båda objekten i hash:en. Det ser till synes ut som om dessa två objekt är identiska men det kan de ju inte vara.
Räknade ut hashvärde för båda objekten och de är inte idenstiska.
Vad kan vara fel? med Point funkar det men med min egen klass så funkar det inte.
kan nämnas att jag kör
contains() metoden för att kontrollera om den valda obketen redan finns i hash:en.
if(hash.contains(op) )
{
// om true så finns det redan ett...om false så är det fritt fram
}
PhorpherMedlem sedan feb. 20002 059 inlägg
hash.add(new java.awt.Point( 10,10) );
hash.add(new java.awt.Point( 10,10) );
Här lägger du till två olika objekt. Visst. Båda punkterna har samma värden men de kan ligga på helt skilda stället i minnet. New allokerar ju nytt minne för ett objekt...
Operator op = new Operator("Kalle", "abc77");
hash.add(op):
hash.add(op);
Här däremot, så allokerar du minne för ett objekt men lägger in samma objekt två gånger i hashen. Och som du sa så går det inte att lägga till samma objekt två ggr. i hashen (Jag har ingen koll på HashSet i java så jag litar på ditt ord när du säger att det inte går). :)
ViktorMedlem sedan aug. 20021 710 inlägg
Jag vet inte om det har någon betydelse men i ditt första exempel skapar du 2 point och försöker lägga till 2 olika objekt. I ditt andra exempel försöker du lägga till samma objekt 2 gånger till din hashset.
/Viktor
jmeMedlem sedan maj 20011 967 inlägg
hmm, i exemplet jag skrev kör jag med samma objekt(op)
men i koden så skapar jag nya objekt och försöker lägga in dem i hash:en
Saken är att jag kan inte lagra två Point objekt som har exakt samma värden men däremot så kan jag lagra två Operator objekt som enligt mig har exakt samma värden( båda har "Kalle" och "abc77") ( new Operator("Kalle", "abc77")
Varför funkar den ena men inte den andra? Blir galen :)
PhorpherMedlem sedan feb. 20002 059 inlägg
Fungerar det om du gör såhär:
hash.add(new Operator("Kalle", "abc77"));
hash.add(new Operator("Kalle", "abc77"));
?? Alltså den andra hash.add returnerar false?
ViktorMedlem sedan aug. 20021 710 inlägg
jme skrev:
hmm, i exemplet jag skrev kör jag med samma objekt(op)
men i koden så skapar jag nya objekt och försöker lägga in dem i hash:en
Saken är att jag kan inte lagra två Point objekt som har exakt samma värden men däremot så kan jag lagra två Operator objekt som enligt mig har exakt samma värden( båda har "Kalle" och "abc77") ( new Operator("Kalle", "abc77")
Varför funkar den ena men inte den andra? Blir galen :)
Utan att veta exakt så tror jag att Hashset tror att du vill updatera det objekt som finns i ditt hashset när du lägger till samma objekt, det får du göra. Om du däremot försöker lägga till ett liknande objekt men inte samma så får du nej, det finns redan ett sådant objekt i ditt hashset.
/Viktor
PeWMedlem sedan juni 20006 839 inlägg
Kan det inte vara en kompilatoroptimering som stökar? Hur är flaggorna satta när du kompilerar?
Utan att veta exakt så tror jag att Hashset tror att du vill updatera det objekt som finns i ditt hashset när du lägger till samma objekt, det får du göra. Om du däremot försöker lägga till ett liknande objekt men inte samma så får du nej, det finns redan ett sådant objekt i ditt hashset.
Verkar skumt om det vore så. Två objekt (även om de är av samma typ och har samma värden) ska få två olika adresser om de skapas med newoperatorn. Däremot kan de få samma hashnyckel beroende på hur denna nyckel plockas fram och hur hashtabellen behandlar den. Där kan det då strula.
Av bl.a den anledningen kan det vara bättre att peta ihop egna hashfunktioner än att använda de färdiga som java har att erbjuda.
Jaja... ska bli skoj att se vad som strular i det här fallet - när han väl hittat felet. :bire
LimeMedlem sedan sep. 2001837 inlägg
Skumt och skumt... Det handlar om hur man skapar hashkoden som PeW så riktigt påpekar. Eftersom du använder dig av annonyma strängar när du skapar dina Operator så får Operator-instanserna samma hashcode, om man inte skriver om getHashCode() så att det alltid returnerar olika för olika objekt.
För att fördjupa... JVM:en tolkar din kod såhär:
String s_tmp1 = "Kalle";
String s_tmp2 = "abc77";
hash.add(new Operator(s_tmp1, s_tmp2));
hash.add(new Operator(s_tmp1, s_tmp2));
Vilket gör att hashcode för s_tmp1 och s_tmp2 är samma och då blir, enligt de aritmetiska regler som används som standard för att räkna ut hashcode för object s_tmp1+s_tmp2 = hc. (Något förenklat...)
java.awt.Point däremot överlagrar getHashCode() för att räkna ut den oberoende av vilket data som finns i den...
Klurigt va?
Du kan ju fundera på vad som skulle hända om man gjorde en clone på Operator och försökte lägga in den... det får man inte. (En clone är en instans med annan adress men samma hc).
/Lime