Avatar billede junl Nybegynder
15. maj 2006 - 20:43 Der er 24 kommentarer og
1 løsning

Indhold i objekter ens - ens hashcode

Okay - det er først gang jeg bevæger mig udi noget med hashcoder, og selvfølgelig kan jeg ikke få det til, at fungere som jeg ønsker det.

Jeg har en hashtable hvori jeg gemmer objekter, af en type som jeg selv har specificeret. Hvert objekt indeholder et 3*3 bytearray. På hver plads i bytearrayet står der enten 0,1 eller 2. Jeg ønsker det sådan, at objekter med ens bytearrays har samme hashcode - da jeg benytter hashcoden (int pakket i Integer objekt) til key i min hashtable. Dvs. adder jeg et objekt til min hashtable, hvor der i forvejen findes et objekt indeholdene samme bytearray - så bliver dette overskrevet.

Indtil nu har min hashcode udregning været at gange indholdet af en plads i bytearrayet med et primtal og ligge alle resultaterne sammen - desværre er det nok ikke unikt. Nogen gode forslag til, hvordan jeg får lavet en unik hashcode som samtidig er ens hvis bytearray'sne er ens?
Avatar billede erikjacobsen Ekspert
15. maj 2006 - 20:45 #1
Den behøver slet ikke være unik. Har du 9 forskellige primtal, sådan lidt langt fra hinanden, så er det vel godt nok.
Avatar billede erikjacobsen Ekspert
15. maj 2006 - 20:48 #2
Og du husker at du også skal lave din equals()-funktion.
Avatar billede arne_v Ekspert
15. maj 2006 - 20:50 #3
Du kan ikke bruge hashcode som key i en HashMap da hashcode ikke skal vaere unik

gem hele objektet

og hvis en Hashtable ikke duer saa maaske en ArrayList eller TreeSet
Avatar billede junl Nybegynder
15. maj 2006 - 20:53 #4
Okay jeg har også overskrevet equals methoden - den ser sådan her ud:

      if (board.getClass() == Board.class) {
          for (int y = 0; y < 3; y++) {
              for (int x = 0; x < 3; x++) {
                  if (((Board)board).checkPos(x,y) != pos[x][y])
                      return false;
              }
          }
          return true;

      }
      else
          return false;

Måske er problemet, at mine primtal ikke ligger langt fra hinanden.

Til arne_v: Selvfølgelig kan jeg bruge hashcoden som key i min hashtable. Og hashcoden skal som sådan heller ikke være unik, objekter med ens bytearrays skal have samme hashcode. Objektet bliver jo gemt sammen med keyen. Jeg forstår måske ikke rigtigt hvor du vil hen.
Avatar billede junl Nybegynder
15. maj 2006 - 20:56 #5
Og min overskrevne hashcode ser sådan her ud:

  public int hashCode() {
    int hash = pos[0][0] *  5 + pos[1][0] *  13 + pos[2][0] *  23 +
              pos[0][1] *  37 + pos[1][1] * 53 + pos[2][1] * 71 +
              pos[0][2] * 83 + pos[1][2] * 101 + pos[2][2] * 167;
    return hash;
  }
Avatar billede arne_v Ekspert
15. maj 2006 - 20:57 #6
"da jeg benytter hashcoden (int pakket i Integer objekt) til key i min hashtable"

antyder ret kraftigt at du bruger:

ht.add(o.hashcode(), o);

og det er ikke godt, da ens hashcoder ikke betyder ens objekter
(men ens objekter betyder ens hashcoder)
Avatar billede arne_v Ekspert
15. maj 2006 - 20:59 #7
og du kan ikke lave en reversibel mapning fra 9 byte til 1 int

(foruden at det ikke er paent at ligge en semantik ind i hashcode som ikke
er tiltaenkt fra SUN's side)
Avatar billede junl Nybegynder
15. maj 2006 - 20:59 #8
Ja jeg bruger ht.add(o.hashcode(), o); men ok, så forstår jeg ikke hvorfor det ikke er godt. Jeg vil jo gerne have at hvis et objekt med den hashcode allerede findes, så overskrives den.
Avatar billede junl Nybegynder
15. maj 2006 - 21:01 #9
Arne_v - du er meget klog mand :-) Men du må lige ned på et lavere niveau hvis jeg skal forstå hvad det er jeg gør forkert. Jeg ved ikke en gang hvad reversibel betyder.
Avatar billede arne_v Ekspert
15. maj 2006 - 21:02 #10
det er umuligt at lave en en hashcode paa 1 int som er unik for alle mulige
kombinationer af 9 byte
Avatar billede arne_v Ekspert
15. maj 2006 - 21:03 #11
jeg tror at du skal:

1)  lave en klasse med kun de 9 bytes, din nuvaerende hashcode  og equals
2)  lave en klasse med klasse #1 osm field og alle de andre felter
    i de nuvaerende klasse

bruge:

ht.add(o.getKlasse1(), o);
Avatar billede junl Nybegynder
15. maj 2006 - 21:04 #12
Okay - så det første jeg skal gøre er at lade være med, at bruge hashcoden som key right? Jeg laver derfor i stedet en key metode i mit objekt og bruger den. Og hvis jeg så bruger et intarray i stedet for et byte, så kan jeg bruge min keyudregning eller hvordan? Og tak for de meget hurtige svar :-)
Avatar billede junl Nybegynder
15. maj 2006 - 21:06 #13
Okay - der skrev jeg lige på samme tid som dig. Jeg er ikke helt klar over hvad #1 osm betyder
Avatar billede erikjacobsen Ekspert
15. maj 2006 - 21:08 #14
Det lyder (som altid) fornuftigt hvad arne_v skriver, og det kommer sikkert til at virke.

Jeg vil blot anbefale at gange større primtal på, for at få en større spredning. Du kan sagtens tage nogen på 4-5 cifre, med 300-1000 imellem.
Avatar billede erikjacobsen Ekspert
15. maj 2006 - 21:11 #15
Avatar billede arne_v Ekspert
15. maj 2006 - 21:12 #16
klasse #1  betyder klassen imaerket med 1)
Avatar billede arne_v Ekspert
15. maj 2006 - 21:13 #17
maerket med
Avatar billede junl Nybegynder
15. maj 2006 - 21:18 #18
Jeg er blevet helt forvirret nu - jeg har ingen idé om hvordan jeg skal implementere det, så det bliver rigtigt :-) Den eneste jeg kunne ønske mig var at lave en key, der kunne bruges sådan at gamle objekter i min hashtable blev overskrevet hvis et nyt med samme array tilføjes.
Avatar billede junl Nybegynder
15. maj 2006 - 21:28 #19
Nå men jeg prøver at gøre som arne_v skriver, men jeg ved bare ikke hvad et osm field er.
Avatar billede junl Nybegynder
15. maj 2006 - 21:30 #20
Ahh - okay nu er jeg da helt væk. Det er jo bare en stavebøf hehe. Undskyld som field naturligvis. Beklager
Avatar billede arne_v Ekspert
16. maj 2006 - 02:50 #21
jeg har for mange tommelfingre på tastaturet
Avatar billede junl Nybegynder
16. maj 2006 - 18:47 #22
Jeg har lavet det om efter arne_v's opskrift. Jeg har lavet et Key objekt som oprettes og returnes når getKey() kaldes i Board. Tak for hjælpen - lig et svar, så er der point.
Avatar billede arne_v Ekspert
16. maj 2006 - 18:55 #23
det virker nu ?
Avatar billede erikjacobsen Ekspert
16. maj 2006 - 20:01 #24
Ingen point til mig, tak.
Avatar billede junl Nybegynder
16. maj 2006 - 22:11 #25
Jeps det virker helt perfekt - da jeg fik rettet det hele til. Mine board objekter (som jeg gemmer i hashtablen) har metoden: 
public Key getKey() {
    return new Key(pos);
}

Og så har jeg flyttet equals og hashcode overskrivningerne over i key objektet. Så jeg gemmer bare med ht.add(board.getKey(), board)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester