Tiedon ryhmittely hajautustaulun avulla
Hajautustaulu sisältää korkeintaan yhden arvon yhtä avainta kohti. Seuraavassa esimerkissä tallennamme henkilöiden puhelinnumeroita hajautustauluun.
HashMap<String, String> puhelinnumerot = new HashMap<>();
puhelinnumerot.put("Pekka", "040-12348765");
System.out.println("Pekan numero: " + puhelinnumerot.get("Pekka"));
puhelinnumerot.put("Pekka", "09-111333");
System.out.println("Pekan numero: " + puhelinnumerot.get("Pekka"));
Pekan numero: 040-12348765 Pekan numero: 09-111333
Entä jos haluaisimme liittää yhteen avaimeen useita arvoja, eli esimerkiksi useampia puhelinnumeroita yhdelle henkilölle?
Koska hajautustaulun avaimet ja arvot voivat olla mitä tahansa muuttujia, myös listojen käyttäminen hajautustaulun arvona on mahdollista. Useamman arvon lisääminen yhdelle avaimelle onnistuu liittämällä avaimeen lista. Muutetaan puhelinnumeroiden tallennustapaa seuraavasti:
HashMap<String, ArrayList<String>> puhelinnumerot = new HashMap<>();
Nyt hajautustaulussa on jokaiseen avaimeen liitettynä lista. Vaikka new-komento luo hajautustaulun, ei hajautustaulu sisällä alussa yhtäkään listaa. Ne on luotava tarvittaessa erikseen.
HashMap<String, ArrayList<String>> puhelinnumerot = new HashMap<>();
// liitetään Pekka-nimeen ensin tyhjä ArrayList
puhelinnumerot.put("Pekka", new ArrayList<>());
// ja lisätään Pekkaa vastaavalle listalle puhelinnumero
puhelinnumerot.get("Pekka").add("040-12348765");
// ja lisätään toinenkin puhelinnumero
puhelinnumerot.get("Pekka").add("09-111333");
System.out.println("Pekan numerot: " + puhelinnumerot.get("Pekka"));
Pekan numero: [040-12348765, 09-111333]
Määrittelimme muuttujan puhelinnumero tyypiksi HashMap<String, ArrayList<String>>
. Tämä tarkoittaa hajautustaulua, joka käyttää avaimena merkkijonoa ja arvona merkkijonoja sisältävää listaa. Hajautustauluun lisättävät arvot ovat siis konkreettisia listoja.
// liitetään Pekka-nimeen ensin tyhjä ArrayList
puhelinnumerot.put("Pekka", new ArrayList<>());
// ...
Vastaavalla tyylillä voi toteuttaa esimerkiksi tehtävien pistekirjanpidon. Alla olevassa esimerkissä on hahmoteltu luokkaa Tehtavakirjanpito
, mikä sisältää käyttäjäkohtaisen pistekirjanpidon. Käyttäjä esitetään merkkijonona ja pisteet kokonaislukuina.
public class Tehtavakirjanpito {
private HashMap<String, ArrayList<Integer>> tehdytTehtavat;
public Tehtavakirjanpito() {
this.tehdytTehtavat = new HashMap<>();
}
public void lisaa(String kayttaja, int tehtava) {
// uudelle käyttäjälle on lisättävä HashMapiin tyhjä lista jos sitä
// ei ole jo lisätty
this.tehdytTehtavat.putIfAbsent(kayttaja, new ArrayList<>());
// haetaan ensin käyttäjän tehtävät sisältävä lista ja tehdään siihen lisäys
ArrayList<Integer> tehdyt = this.tehdytTehtavat.get(kayttaja);
tehdyt.add(tehtava);
// edellinen olisi onnitunut myös ilman apumuuttujaa seuraavasti
// this.tehdytTehtavat.get(kayttaja).add(tehtava);
}
public void tulosta() {
for (String nimi: tehdytTehtavat.keySet()) {
System.out.println(nimi + ": " + tehdytTehtavat.get(nimi));
}
}
}
Tehtavakirjanpito kirjanpito = new Tehtavakirjanpito();
kirjanpito.lisaa("Ada", 3);
kirjanpito.lisaa("Ada", 4);
kirjanpito.lisaa("Ada", 3);
kirjanpito.lisaa("Ada", 3);
kirjanpito.lisaa("Pekka", 4);
kirjanpito.lisaa("Pekka", 4);
kirjanpito.lisaa("Matti", 1);
kirjanpito.lisaa("Matti", 2);
kirjanpito.tulosta();
Matti: [1, 2] Pekka: [4, 4] Ada: [3, 4, 3, 3]
Muistathan tarkistaa pistetilanteesi materiaalin oikeassa alareunassa olevasta pallosta!