Föreläsning 11 Innehåll

Relevanta dokument
Föreläsning 10 Innehåll

Föreläsning 10 Innehåll. Diskutera. Hashtabeller. Hashfunktion. hashfunktion. hashkod (ett heltal)

Diskutera. Hashfunktion

Inlämningsuppgift och handledning

Inlämningsuppgift och handledning. Föreläsning 11 Innehåll. Diskutera. Hashtabeller

Interfacen Set och Map, hashtabeller

Föreläsning 14 Innehåll

Föreläsning 9 Innehåll

Hitta k största bland n element. Föreläsning 13 Innehåll. Histogramproblemet

Tentamen, EDAA01 Programmeringsteknik fördjupningskurs

Föreläsning 8. Mängd, Avbildning, Hashtabell

Föreläsning 10 Innehåll. Diskutera. Inordertraversering av binära sökträd. Binära sökträd Definition

Föreläsning 10 Innehåll

Avbildningar och hashtabeller. Koffman & Wolfgang kapitel 7, mestadels avsnitt 2 4

Föreläsning 11 Innehåll. Diskutera. Binära sökträd Definition. Inordertraversering av binära sökträd

Föreläsning 8. Mängd, Avbildning, Hashtabell

Föreläsning 2 Innehåll

Java Collections Framework. Föreläsning 2 Innehåll. Java Collections Framework interface hierarki. Java Collections Framework interface hierarki

Seminarium 3 Introduktion till Java Collections Framework Innehåll. Generik Bakgrund. Exempel på en generisk klass java.util.arraylist.

Programmering fortsättningskurs

Samlingar Collection classes

Föreläsning 4 Innehåll. Abstrakta datatypen lista. Implementering av listor. Abstrakt datatypen lista. Abstrakt datatyp

Innehåll. Föreläsning 10. Specifikation. Mängd. Specifikation. Konstruktion av mängd. Mängd Lexikon Hashtabell

Föreläsning 10 Innehåll. Prioritetsköer och heapar. ADT Prioritetskö. Interface för Prioritetskö. Exempel på vad du ska kunna

Seminarium 2 Introduktion till Java Collections Framework Innehåll. Generik Bakgrund. Exempel på en generisk klass java.util.arraylist.

ADT Prioritetskö. Föreläsning 13 Innehåll. Prioritetskö vs FIFO-kö. Prioritetskö Exempel på användning. Prioritetsköer och heapar

Föreläsning 4 Innehåll

Datastrukturer som passar för sökning. Föreläsning 10 Innehåll. Inordertraversering av binära sökträd. Binära sökträd Definition

Föreläsning 2 Innehåll

Datastrukturer och algoritmer. Innehåll. Tabell. Tabell - exempel. Gränsyta till Tabell. Tabell. Modell. Hashtabell Relation, lexikon.

Datastrukturer som passar för sökning. Föreläsning 11 Innehåll. Binära sökträd Definition. Inordertraversering av binära sökträd

Algoritmer och datastrukturer

ADT Prioritetskö. Föreläsning 12 Innehåll. Prioritetskö. Interface för Prioritetskö. Prioritetsköer och heapar

Datastrukturer. föreläsning 6. Maps 1

Objektorienterad Programmering DAT043. Föreläsning 9 12/2-18 Moa Johansson (delvis baserat på Fredrik Lindblads material)

Programmering för språkteknologer II, HT2014. Rum

Java Collections Framework. Föreläsning 2 Innehåll. Java Collections Framework interface hierarki. Java Collections Framework interface hierarki

Föreläsning 2 Innehåll. Generiska klasser. Generik i Java. Varför generiska klasser Bakgrund

Abstrakt datatyp. -Algoritmer och Datastrukturer- För utveckling av verksamhet, produkter och livskvalitet.

Tentamen, EDAA01 Programmeringsteknik fördjupningskurs

Programmering för språkteknologer II, HT2011. Rum

Seminarium 13 Innehåll

13 Prioritetsköer, heapar

Tentamen, EDAA01 Programmeringsteknik fördjupningskurs

Samlingar Collection classes

Länkade strukturer. (del 2)

Sökning. Översikt. Binärt sökträd. Linjär sökning. Binär sökning. Sorterad array. Linjär sökning. Binär sökning Hashtabeller

Föreläsning 9 Datastrukturer (DAT037)

Tentamen, EDA690 Algoritmer och Datastrukturer, Helsingborg

Föreläsning 13 Innehåll

F5: Debriefing OU2, repetition av listor, träd och hashtabeller. Carl Nettelblad

Föreläsning 5 Datastrukturer (DAT037)

Algoritmer och datastrukturer 2012, fo rela sning 8

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 9 Jonas Lindgren, Institutionen för Datavetenskap, LiU

Föreläsning Datastrukturer (DAT036)

Hashtabeller. TDA416, lp3 2016

Lösningsförslag till tentamen i EDAA01 programmeringsteknik fördjupningkurs

Lösningsförslag till tentamen i EDA690 Algoritmer och Datastrukturer, Helsingborg

Objektorienterad Programkonstruktion. Föreläsning 9 30 nov 2016

Sortering. Föreläsning 12 Innehåll. Sortering i Java. Sortering i Java Exempel. Sortering

Föreläsning 9 Innehåll

Föreläsning 12 Innehåll

Tentamen, EDAA01 Programmeringsteknik fördjupningskurs

Binära sökträd. Seminarium 9 Binära sökträd Innehåll. Traversering av binära sökträd. Binära sökträd Definition. Exempel på vad du ska kunna

Tommy Färnqvist, IDA, Linköpings universitet. 1 ADT Map/Dictionary Definitioner Implementation... 2

Föreläsning 7. Träd och binära sökträd

Magnus Nielsen, IDA, Linköpings universitet

Föreläsning 10 Datastrukturer (DAT037)

Tommy Färnqvist, IDA, Linköpings universitet. 1 ADT Map/Dictionary Definitioner Implementation... 2

Tentamen Programmeringsteknik II och NV2 (alla varianter) Skriv bara på framsidan av varje papper.

Collection classes. Interface, första exempel. Interface (forts) Men först

F12 - Collections. ID1004 Objektorienterad programmering Fredrik Kilander

Datastrukturer i kursen. Föreläsning 8 Innehåll. Träd rekursiv definition. Träd

Listor. Koffman & Wolfgang kapitel 2, avsnitt , och 2.9

Innehåll. F7: Tabell, hashtabell, relation & lexikon. Gränsyta till Tabell. Tabell. Tabell Hashtabell Relation Lexikon.

TDDE10 m.fl. Objektorienterad programmering i Java Föreläsning 5 Erik Nilsson, Institutionen för Datavetenskap, LiU

Datastrukturer. Arrayer. Arrayer. Arrayer. Array av arrayer. Array av arrayer

TENTAMEN: Algoritmer och datastrukturer. Läs detta! Uppgifterna är inte avsiktligt ordnade efter svårighetsgrad.

Tentamen, EDAA01 Programmeringsteknik fördjupningskurs

Inlämningsuppgiften. Föreläsning 9 Innehåll. Träd. Datastrukturer i kursen

Länkade strukturer, parametriserade typer och undantag

Collection Classes. bjectorienterad programmering Sida 1

Föreläsning 4 Datastrukturer (DAT037)

Datastrukturer och algoritmer

Programmering för Språkteknologer II. Innehåll. Associativa datastrukturer. Associativa datastrukturer. Binär sökning.

Lösningsförslag till tentamen Datastrukturer, DAT037,

EDAA20 Föreläsning Klassen ArrayList. Viktiga operationer på ArrayList. Generisk klass

Tentamen i Algoritmer & Datastrukturer i Java

Tentamen Programmeringsteknik II Inledning. Anmälningskod:

Repetition av OOP- och Javabegrepp

Föreläsning 5 Innehåll

Repetition av OOP- och Javabegrepp

Datastrukturer. föreläsning 3. Stacks 1

Datastrukturer. föreläsning 10. Maps 1

TDDC77 Objektorienterad Programmering

Tentamen Objekt-orienterad programmering i Java, 5p distanskurs

Föreläsning 7 Innehåll. Rekursion. Rekursiv problemlösning. Rekursiv problemlösning Mönster för rekursiv algoritm. Rekursion. Rekursivt tänkande:

Innehåll. Sökning och hashtabeller. En bilsamling att söka i. En bil-klass att söka efter. Hur hittar vi alla bilar som uppfyller ett annat villkor

TENTAMEN PROGRAMMERINGSMETODIK MOMENT 2 - JAVA, 4P

Föreläsning 7. Träd och binära sökträd

Transkript:

Föreläsning 11 Innehåll Hashtabeller implementering, effektivitet Metoden hashcode i Java Abstrakta datatyperna mängd (eng. Set) och lexikon (eng. Map) Interfacen Set och Map i Java Datavetenskap (LTH) Föreläsning 11 VT 2019 1 / 54

Diskutera Som vi tidigare sett kan man använda binära sökträd för att lagra data som man snabbt ska kunna söka i. Tidskomplexiteten för att sätta in, söka och ta bort element i ett balanserat binärt sökträd är O(logn). Antag att vi har fått i uppdrag att skriva ett program som hanterar medlemmar i en förening. Antalet medlemmar är max 1000 st. Varje medlem har ett unikt medlemsnummer mellan 0 och 999. Detta nummer används som nyckel för att identifiera och söka efter en medlem. Finns det något bättre (snabbare, enklare) sätt än binärt sökträd för att lagra medlemmarna i just detta specialfall? Datavetenskap (LTH) Föreläsning 11 VT 2019 2 / 54

Hashtabeller Antag att de nycklar som ska användas vid sökningen är heltal i intervallet 0..n 1. En vektor med n platser kan användas. Elementet med nyckel k placeras på plats k i vektorn. Sökning, insättning och borttagning av k blir en direkt access till plats k. Alla dessa operationer har tidskomplexitet O(1). Idéen kan generaliseras till alla slags objekt: Nycklarna översätts till ett heltal i intervallet 0..n-1. Datavetenskap (LTH) Föreläsning 11 VT 2019 3 / 54

Hashfunktion Idé: översätt nycklar till heltal som kan användas som index i en vektor. hashfunktion nyckel hashkod (ett heltal) Hashfunktionen avbildar nyckeln på heltal (hashkod). hashkod % table.length kan användas som index i en vektor table. Kollisioner (olika nycklar får samma index) är oundvikliga och måste hanteras. En bra hashfunktion bör påverkas av alla delar av nyckeln. ger litet förväntat antal kollisioner, sprider elementen över hela tabellen. Datavetenskap (LTH) Föreläsning 11 VT 2019 4 / 54

Hashfunktion Från nyckel till hashkod Om nyckeln är ett heltal kan hashkoden vara talet självt. För en sträng s 0 s 1 s 2...s n 1 är en lämplig hashfunktion s[0] 31 n 1 + s[1] 31 n 2 +... + s[n 1] Ger ett stort heltal. Tecken i olika positioner multipliceras med olika potenser av 31. Permutationer av samma tecken ger därför olika hashkod. 31 är ett primtal och det kan visas att man därför får relativt få kollisioner. Datavetenskap (LTH) Föreläsning 11 VT 2019 5 / 54

Metoden hashcode i Java I klassen Object finns en metod hashcode som översätter ett objekt till ett heltal. Den är implementerad så att olika objekt om möjligt avbildas på olika heltal. Metoden hashcode är skuggad i Javas klasser (String, Integer...) så att lika objekt avbildas på samma heltal. Man måste skugga hashcode (och equals) i den klass vars objekt ska fungera som nyckel i Javas hashtabellsklasser. Objekt för vilka equals ger true ska få samma hashkod. Datavetenskap (LTH) Föreläsning 11 VT 2019 6 / 54

Från hashkod till index i tabellen Index i vektorn kan räknas ut så här: int index = key.hashcode() % table.length; if (index < 0 ) { index = index + table.length; } Math.abs kan ge ett negativt resultat och används därför inte här. (Math.abs(Integer.MIN_VALUE) blir negativt pga. overflow.) Det går att använda Math.abs ändå om man tänker sig för: int index = Math.abs(k % table.length); int index = Math.abs(k) % table.length; // fungerar // fungerar INTE Det finns andra sätt att räkna ut index utgående från hashkoden som bättre sprider ut nycklarna över tabellen. Datavetenskap (LTH) Föreläsning 11 VT 2019 7 / 54

Diskutera Försök sätta in element med nycklarna 1, 8, 27, 64, 6 ska sättas in i en tabell med 7 platser. Elementets index = x % 7. 0 1 2 3 4 5 6 Hur hanterar man kollisioner (dvs. att olika nycklar får samma index)? Datavetenskap (LTH) Föreläsning 11 VT 2019 8 / 54

Hashtabeller olika alternativ Det finns olika sätt att implementera hashtabeller. Öppen hashtabell (eng: separate chaining) en vektor av listor Kolliderande objekt placeras i samma lista. Sluten hashtabell (eng: open addressing) en vektor används för att lagra elementen Det finns sedan olika sätt att hantera kollisioner t ex linjär teknik kvadratisk teknik Datavetenskap (LTH) Föreläsning 11 VT 2019 9 / 54

Öppen hashtabell (separate chaining) Elementen i tabellen är listor. I lista nummer k ligger alla element vars nyckel har hashkod % table.length = k. 0 1 2 table.length-2 table.length-1 Datavetenskap (LTH) Föreläsning 11 VT 2019 10 / 54

Öppen hashtabell (separate chaining) Exempel Sätt in element med nycklarna 1, 8, 27, 64, 6 i en öppen tabell med 7 listor. 0 1 64 8 1 2 3 4 5 6 6 27 Datavetenskap (LTH) Föreläsning 11 VT 2019 11 / 54

Sluten hashtabell med linjär kollisionsteknik Vid linjär teknik sätter man in ett element som kolliderar med ett annat på första lediga plats efter den där det skulle ha hamnat om ingen kollision inträffat. Tabellen betraktas som cirkulär, d.v.s. index 0 anses komma efter tablesize-1. 6 1 8 64 27 0 1 2 3 4 5 6 Sökning efter visst element börjar på den plats elementets hashkod anger och fortsätter eventuellt framåt. Om det inte påträffas före en ledig plats finns det inte i tabellen. Datavetenskap (LTH) Föreläsning 11 VT 2019 12 / 54

Borttagning i sluten hashtabell med linjär kollisionsteknik Om vi vid borttagning bara gör platsen tom, leder det till fel vid sökning. Ex: Tag bort 1 ur tabellen på föregående bild: 6 8 64 27 0 1 2 3 4 5 6 Om vi nu söker efter 8 vars hashkod % 7 är 1 börjar vi pröva plats 1. Eftersom denna plats är tom sluter vi oss felaktigt till att det sökta elementet inte finns i tabellen. Datavetenskap (LTH) Föreläsning 11 VT 2019 13 / 54

Borttagning i sluten hashtabell med linjär kollisionsteknik Forts Om vi i stället markerar platsen icke-aktiv vid borttagning (i fig. nedan markerat med ett d): 6 d 8 64 27 0 1 2 3 4 5 6 så kan vi utföra sökningen med början på den plats hashkod % 7 anger och framåt över alla upptagna och icke-aktiva platser. Först när vi stöter på en riktigt tom plats är det misslyckad sökning. Datavetenskap (LTH) Föreläsning 11 VT 2019 14 / 54

Problem med linjär teknik Linjär teknik ger upphov till primär klustring i tabellen. Om flera objekt kolliderar (får samma index pos) kommer de att ligga i ett kluster kring platsen pos. Även objekt vars hashkoder är nära pos kommer att drabbas av kollisioner och bygga ut klustret. Stora kluster gör sökning långsam. Ex: Sätt in element med nycklarna 3, 13, 23, 33, 5, 15. 3 13 23 33 5 15 0 1 2 3 4 5 6 7 8 9 Datavetenskap (LTH) Föreläsning 11 VT 2019 15 / 54

Sluten hashtabell, kvadratisk kollisionsteknik Alternativ, bättre teknik för hantering av kollisioner. Först prövas nästa plats, sedan platsen 4 steg fram, sedan 9 steg fram, alltså pos, pos + 1, pos + 2 2, pos + 3 2,..., pos + i 2,... där pos är elementets hashkod. Tabellen används fortfarande cirkulärt. Undviker primär klustring av element. Kan modifieras till andra sekvenser av steg. Datavetenskap (LTH) Föreläsning 11 VT 2019 16 / 54

Sluten hashtabell, kvadratisk kollisionsteknik Exempel Sätt in element med nycklarna 89, 18, 49, 58, 9 i en tabell med 10 platser. 89 % 10 = 9 18 % 10 = 8 49 % 10 = 9 58 % 10 = 8 9 % 10 = 9 49 58 9 0 1 2 3 4 5 6 7 18 89 8 9 Datavetenskap (LTH) Föreläsning 11 VT 2019 17 / 54

Sluten hashtabell, kvadratisk kollisionsteknik Problem: Inte alltid säkert att man hittar ledig plats även om det finns. Om t ex tabellens storlek är 16 och man använder hashfunktionen x % 16 och sätter in element med nycklarna 0, 16, 32 och 64 så kan man inte därefter hitta någon ledig plats för element som hashas till plats 0. De enda platser som kommer att prövas i serien pos + i 2 när pos = 0 blir de upptagna platserna 0, 1, 4 och 9. Om tabellens storlek är ett primtal kan ett nytt element alltid sättas in om tabellens fyllnadsgrad är mindre än 0.5. Datavetenskap (LTH) Föreläsning 11 VT 2019 18 / 54

Diskutera Vilka faktorer påverkar antal kollisioner i en hashtabell? Vilka konsekvenser får ett högt antal kollisioner i en hashtabell? Hur kan risken för kollisioner minskas? Datavetenskap (LTH) Föreläsning 11 VT 2019 19 / 54

Vad påverkar antal kollisioner? Nycklarna är unika. Hashkoden beräknas med en hashfunktion som avbildar nycklarna på heltal. Olika nycklar kan få samma hashkod. Hashkoden måste anpassas till tabellens storlek. Som index i tabellen kan t.ex. hashkod % table.length användas. Olika hashkod kan ge samma index. Risken för kollisioner (flera element med samma index) ökar om hashfunktionen är dåligt vald. tabell är för liten. Datavetenskap (LTH) Föreläsning 11 VT 2019 20 / 54

Fyllnadsgrad Fyllnadsgrad (eng. load factor) = antal insatta element/antal platser i tabellen. Valet av fyllnadsgrad är en kompromiss mellan minnesåtgång och tidsåtgång. Ett lämpligt val av fyllnadsgrad i en öppen tabell är 0.75. En sluten tabell bör inte fyllas mer än hälften. Datavetenskap (LTH) Föreläsning 11 VT 2019 21 / 54

Tidskomplexitet Sökning (och därmed insättning och borttagning) i en hashtabell innebär beräkning av index sökning bland kolliderande nycklar Värstafallet för sökning, insättning och borttagning är O(n), där n är antalet element som finns insatta i tabellen. Inträffar om alla element hamnar i en lista (öppen tabell)/följd (sluten tabell). Då måste vi vid sökning måste pröva alla nycklarna i denna lista/följd. Är dock ytterst osannolikt. Tidskomplexiteten är O(1) i medelfall (och i praktiken med en bra hashfunktion och med en tillräckligt stor tabell). Datavetenskap (LTH) Föreläsning 11 VT 2019 22 / 54

Rehashing Om fyllnadsgraden blir för stor måste man bygga om tabellen: Skapa en dubbelt så stor tabell. Sätt in alla element i den nya tabellen. 0 1 2 3 4 5 6 64 8 1 0 1 1 25 6 27 2 3 4 5 6 6 7 8 8 9 10 11 25 12 13 27 64 Datavetenskap (LTH) Föreläsning 11 VT 2019 23 / 54

Öppen hashtabell vs. sluten hashtabell Borttagning är enklare i en öppen hashtabell än i en sluten. Elementet tas helt enkelt bort ur den lista där det befinner sig. Vi får inga problem med luckor som i den slutna tabellen. Problem med klustring i slutna tabeller. Slutna tabeller kan behöva mindre minne förutsatt att elementen inte är för stora. I Javas klasser HashSet och HashMap används öppna tabeller. På laboration 6 får du implementera en öppen hashtabell med enkellänkade listor. Datavetenskap (LTH) Föreläsning 11 VT 2019 24 / 54

Abstrakta datatyperna mängd och map Mängd En mängd (eng. Set) är en en samling element där dubbletter är förbjudna. Operationer: Map sätta in add(element) ta bort remove(element) undersöka om ett element finns i mängden contains(element) En map är en en samling nyckel-värde-par. Nycklarna är unika. Operationer: sätta in put(nyckel, värde) ta bort remove(nyckel) söka värdet som hör till en nyckel get(nyckel) Datavetenskap (LTH) Föreläsning 11 VT 2019 25 / 54

Implementera en mängd Både ett balanserat binärt sökträd eller en hashtabell passar bra: Innehåller ej dubbletter. Det är effektivt att sätta in ett element ta bort ett element undersöka om ett element finns. Tidskomplexiteten för dessa operationer är O( 2 log n) i ett balanserat binärt sökträd. O(1) i medelfall i en hashtabell. (Räkna med O(1) om hashfunktion och tabellstorlek valts på ett bra sätt.) Hashtabellen är snabbare i praktiken. Ett binärt sökträd som traverseras i inorder ger elementen i stigande ordning. Datavetenskap (LTH) Föreläsning 11 VT 2019 26 / 54

Implementera en mängd Binärt sökträd Exempel på hur mängden 27, 8, 64 kan lagra i ett binärt sökträd: root size 3 data left right 27 8 data left right null null data left right null null 64 Datavetenskap (LTH) Föreläsning 11 VT 2019 27 / 54

Implementera en mängd Hashtabell Exempel på hur mängden 27, 8, 64 kan lagra i en hashtabell: 0 1 2 null null data next 64 data next null 8 3 null 4 5 null null 27 6 data next null Datavetenskap (LTH) Föreläsning 11 VT 2019 28 / 54

Abstrakt datatypen map En map innehåller nyckel-värde-par Nyckeln avbildas (eng. maps) på sitt värde. Nycklarna är unika, men inte värdena. Man använder nyckeln för att söka tillhörande värde. Exempel: nyckel = månad, värde = antal dagar i månaden. nycklar (unika)... mars april maj... värden (dubbletter ok)... 31 30 31... Datavetenskap (LTH) Föreläsning 11 VT 2019 29 / 54

Diskutera Hur kan vi använda ett binärt sökträd eller en hashtabell för att implementera en Map? Jämför mängd (ett element). I en map ska nyckel och värde lagras tillsammans. Datavetenskap (LTH) Föreläsning 11 VT 2019 30 / 54

Implementera en map Lagra nyckel och värde tillsammans i ett objekt Vi deklarerar en nästlad klass, Entry, som representerar par (nyckel,värde) och sätter in objekt av denna typ i trädet eller hashtabellen. Binärt sökträd Vid jämförelser är det nycklarnas värden som ska jämföras. root size 12 data left right key value "April" 30 Datavetenskap (LTH) Föreläsning 11 VT 2019 31 / 54

Implementera en map Forts. Hashtabell Hashkoden beräknas på nyckeln (key). I exemplet nedan är Entry-objekten samtidigt noder i en enkellänkad lista (därav attributet next). Nycklar som kolliderat hamnar i samma lista. "Mars" "Oktober" 0 1 2 null key value next 31 key value next null 31 3 4 5 6 null............ key value null next "December" 31 Datavetenskap (LTH) Föreläsning 11 VT 2019 32 / 54

Interfacen Set och Map i java.util <<Interface>> Iterable <<Interface>> Collection <<Interface>> Queue <<Interface>> List <<Interface>> Set <<Interface>> Map <<Interface>> SortedSet <<Interface>> SortedMap Datavetenskap (LTH) Föreläsning 11 VT 2019 33 / 54

Interfacet Set En mängd (Set) är en samling element som inte innehåller dubbletter. Metoderna i interfacet Set finns även i interfacet Collection. De har dock olika kontrakt genom att Set inför restriktionen att inga dubbletter får förekomma. Enligt specifikationen i Java får en mängd (Set) innehålla null-element. Men bara ett null-element, p.g.a. dubblettförbudet. Vissa konkreta implementeringar av interfacet Set i java.util förbjuder dock insättning av null. Datavetenskap (LTH) Föreläsning 11 VT 2019 34 / 54

Interfacet SortedSet Förutsätter att elementen som sätts in går att jämföra med varandra. Elementen ska antingen implementera interfacet Comparable eller genom att man (via konstruktorn) anger ett Comparator-objekt som kan användas för jämförelser. Vi återkommer till detta. Garanterar att operationen iterator() returnerar en iterator som går igenom mängden i växande ordning. Utvidgar Set-interfacet med några operationer som återspeglar att elementen går att ordna. Exempel: returnera minsta element, returnera största... Datavetenskap (LTH) Föreläsning 11 VT 2019 35 / 54

Klasser som implementerar Set TreeSet implementerar det utvidgade interfacet SortedSet. Använder ett slags balanserat träd, inte AVL-träd utan röd-svarta träd (eng. Red-Black trees), som också garanterar att höjden är O( 2 log n). HashSet Använder öppen hashtabell. <<Interface>> Set <<Interface>> SortedSet HashSet TreeSet Datavetenskap (LTH) Föreläsning 11 VT 2019 36 / 54

Interfacet Set Abstrakta klasser <<Interface>> Collection betyder ärver från ("extends") AbstractCollection <<Interface>> Set betyder implementerar ("implements") AbstractSet <<Interface>> SortedSet HashSet TreeSet Datavetenskap (LTH) Föreläsning 11 VT 2019 37 / 54

Interfacet Set Abstrakta klasser Kommentarer till hierarkin på föregående bild: Ibland kan man implementera vissa operationer med hjälp av andra operationer i samma interface. Ex: isempty size() == 0 För att underlätta för den som ska implementera ett (stort) interface kan man implementera en abstrakt klass som innehåller implementeringar av vissa metoder enligt detta mönster. Ex: klasserna AbstractCollection och AbstractSet Implementatören av en konkret klass kan då ärva den abstrakta klassen och behöver sedan bara implementera återstående operationer i interfacet. Ex: klasserna TreeSet och HashSet. Datavetenskap (LTH) Föreläsning 11 VT 2019 38 / 54

Klassen TreeSet Implementerar interfacet SortedSet. Det finns flera konstruktorer i klassen, bl.a: 1 public TreeSet(); 2 public TreeSet(Comparator<? super E> c); Används den första konstruktorn, förutsätts elementen implementera Comparable annars genereras ClassCastException. Den andra konstruktorn har en parameter som är ett objekt av en klass som implementerar interfacet Comparator. Används denna kommer jämförelser att utföras med hjälp av komparatorn. Datavetenskap (LTH) Föreläsning 11 VT 2019 39 / 54

Exempel på användning av klassen TreeSet Comparable<E> // Denna mängd kommer att ordnas efter idnummer Set<Person> nbrset = new TreeSet<Person>(); set.add(new Person("Fili", 1)); set.add(new Person("Balin", 2));... // Undersök om personen med idnummer 2 finns i mängden System.out.println(set.contains(new Person(null, 2))); Klassen Person måste implementera Comparable<Person>. I metoden compareto jämförs personernas personnummer. Datavetenskap (LTH) Föreläsning 11 VT 2019 40 / 54

Exempel på användning av klassen TreeSet Komparator // Denna mängd kommer att ordnas efter namn Set<Person> nameset = new TreeSet<Person>((p1, p2) -> p1.getname().compareto(p2.getname())); set.add(new Person("Fili", 1)); set.add(new Person("Balin", 2));... // Undersök om personen med namnet Balin finns i mängden System.out.println(set.contains(new Person("Balin", -1))); Alternativt kan man skriva en klass, NameComparator, som implementerar interfacet Comparator. I metoden compare ska personernas namn jämföras. Mängden skapas då på detta sätt: Set<Person> nameset = new TreeSet<Person>(new NameComparator()); Datavetenskap (LTH) Föreläsning 11 VT 2019 41 / 54

Exempel på användning av klassen HashSet Antag vi vill vill sätta in Person-objekt i en mängd av typen HashSet. HashSet<Person> set = new HashSet<Person>(); Person p = new Person("Balin", 2); set.add(p);... boolean found = set.contains(new Person(null, 2)); Nu måste equals och hashcode skuggas i klassen Person. I equals ska idnnumren jämföras. I hashcode ska en hashkod för idnumret beräknas och returneras. Datavetenskap (LTH) Föreläsning 11 VT 2019 42 / 54

Skugga metoderna equals och hashcode Inuti klasserna HashSet och HashMap används metoderna hashcode() och equals(object) för att hitta ett element: Först beräknas index för elementet baserat på key.hashcode(). Ungefär så här: int index = nyckeln.hashcode() % table.length Sedan söks nyckeln i listan på platsen index. I samband med denna sökning används equals. Datavetenskap (LTH) Föreläsning 11 VT 2019 43 / 54

Vad händer om vi glömmer skugga equals och hashcode Om vi glömmer att skugga hashcode och/eller equals i klassen Person hittar vi troligen inte personen. När personen p sätts in beräknas hashkoden för objektet som p refererar till. När vi söker efter personen baseras sökningen på hashkoden av det objekt som är parameter till contains-metoden. Detta är ett annat objekt (men med samma idnummer). Om vi glömmer skugga hashcode och/eller equals används de ursprungliga metoderna i klassen Object. Då får vi med stor sannolikhet olika hashkod för olika person-objekt även om de har innehåller idnummer. Två person-objekt kommer att betraktas som olika trots att de har samma idnummer. Datavetenskap (LTH) Föreläsning 11 VT 2019 44 / 54

Klass som skuggar equals och hashcode Klassen Person public class Person { private String name; private int id; } // konstruktor och övriga metoder public boolean equals(object other) { if (other instanceof Person) { return id == ((Person) other).id; } else { return false; } } public int hashcode() { return id; } Datavetenskap (LTH) Föreläsning 11 VT 2019 45 / 54

Interfacet Map i java.util <<Interface>> Map AbstractMap <<Interface>> SortedMap HashMap TreeMap Datavetenskap (LTH) Föreläsning 11 VT 2019 46 / 54

Klasser som implementerar Map TreeMap implementerar interfacet SortedMap. Använder balanserat binärt sökträd (röd-svart träd) Om man itererar genom nycklarna får man dem i växande ordning. Ytterligare operationer som bygger på ordning mellan nycklarna finns. HashMap Använder öppen hashtabell. <<Interface>> Map <<Interface>> SortedMap HashMap TreeMap Datavetenskap (LTH) Föreläsning 11 VT 2019 47 / 54

Interfacet Map - ett urval av metoderna public interface Map<K,V> { V get(object key); boolean isempty(); V put(k key, V value); V remove(object key); int size(); Set<K> keyset(); Collection<V> values(); Set<Map.Entry<K,V>> entryset(); } public interface Entry<K,V> { K getkey(); V getvalue(); V setvalue(v); } Interfacet Map ärver inte interfacet Collection eller Iterable. Det går alltså inte att iterera direkt över mappen. Däremot kan man iterera över nycklarna, värdena och nyckel-värdeparen. Datavetenskap (LTH) Föreläsning 11 VT 2019 48 / 54

Exempel på användning av klassen HashMap/TreeMap Map<String, Integer> map = new HashMap<String, Integer>(); //Map<String, Integer> map = new TreeMap<String, Integer>(); map.put("januari", 31); map.put("februari", 28); map.put("mars", 31); map.put("april", 30); map.put("maj", 31);... System.out.println("Antal dagar i mars: " + map.get("mars")); I en HashMap är det nyckelklassen som ska skugga equals och hashcode. I en TreeMap är det nyckelklassen som ska implementera Comparable (om man inte använder konstrukton med en parametar av typen Comparator.) I exemplet har nycklarna typen String där är ovanstående redan fixat. Datavetenskap (LTH) Föreläsning 11 VT 2019 49 / 54

Exempel på användning av klassen HashMap/TreeMap På lab. 4 använde du en HashMap<Side, Point> för att lagra en sidas mittpunkt: Map<Side, Point> midpoints = new HashMap<>(); Eftersom nycklarna var av typen Side var du tvungen att skugga equals och hashcode i klassen Side. public class Side { private Point p1, p2;... public boolean equals(object obj) {...} } public int hashcode() {...} Datavetenskap (LTH) Föreläsning 11 VT 2019 50 / 54

Interfacet Map.Entry Map.Entry är ett inre interface som är nästlat i interfacet Map. /* Representerar ett nyckel-värdepar */ public interface Entry<K,V> { K getkey(); V getvalue(); V setvalue(v); // ändrar värdet till V och // returnerar det gamla värdet } Operationen entryset returnerar en mängd (Set) av Entry-objekt. d.v.s. objekt av en klass som implementerar interfacet Map.Entry Datavetenskap (LTH) Föreläsning 11 VT 2019 51 / 54

Exempel på användning av klassen HashMap/TreeMap Forts. En Map används normalt för att med nyckeln hitta motsvarande värde. Ibland behöver man göra tvärtom: System.out.println("Månader med 31 dagar:"); for (Map.Entry<String, Integer> e : map.entryset()) { if (e.getvalue() == 31) { System.out.println(e.getKey()); } } Metoden entryset returnerar en mängd med alla nyckel-värde-par. Genom att traversera denna mängd kan vi ta reda på vilka nyckel-värde-par som har värdet 31 och skriva ut motsvarande nyckel. Datavetenskap (LTH) Föreläsning 11 VT 2019 52 / 54

Exempel på vad du ska kunna Förklara begreppen hashtabell och hashfunktion. Definiera vad som menas med sluten och öppen hashtabell och hur kollisioner hanteras i sådana tabeller. Förklara vad som menas med fyllnadsgraden (eng: load factor) för en hashtabell. Förklara hur sökning, insättning och borttagning går till i slutna respektive öppna hashtabeller. Implementera öppna hashtabeller (görs på laboration 6). Ange tidskomplexiteten för operationer på hashtabell. Förklara vad de abstrakta datatyperna set och map är och vilka operationer man förväntas kunna utföra på dem. Använda interfacen Set och Map och deras implementerande klasser i Java Collections Framework. Datavetenskap (LTH) Föreläsning 11 VT 2019 53 / 54

Datorlaboration 6 Map, hashtabell Implementera en map med en egen öppen hashtabell. 0 1 2 null null key value next key value next null 3 null 4 null... table.length -1... key value null next Tips: Det ska vara en öppen hashtabell. Entry-objekten fungerar även som noder i en enkellänkad lista. Innehåll: abstrakta datatypen map, öppen hashtabell, länkade listor, generisk klass Datavetenskap (LTH) Föreläsning 11 VT 2019 54 / 54