// Laukku.java SJ import java.util.Iterator; import java.util.Map; /** * Abstrakti tietotyyppi Laukku. * Kokoelma jossa kukin alkio voi olla useamman kerran. * Operaatiot huomioivat alkioiden esiintymismäärät. * null ei kelpaa alkioksi. * @param alkiotyyppi */ public interface Laukku extends Iterable { /** * Lisää alkion x laukkuun. * Jos alkio oli jo laukussa, lisää määrää. * @param x lisättävä alkio * @return aina true */ default boolean lisaa(E x) { return lisaa(x, 1); } /** * Lisää alkion x laukkuun kpl kertaa. * Jos alkio oli jo laukussa, lisää määrää. * Jos kpl<=0, ei tee mitään. * @param x lisättävä alkio * @param kpl montako kappaletta * @return true jos lisäys tehtiin (kpl > 0) */ boolean lisaa(E x, int kpl); /** * Postaa yhden kappaleen alkiota x laukusta jos se siellä on. * @param x poistettava alkio. * @return true jos poisto onnistui, false jollei alkiota ollut. */ default boolean poista(E x) { return (poista(x, 1) == 1); } /** * Poistaa kpl kappaletta alkiota x laukusta jos niitä on riittävästi. * Jos alkioita on vähemmän kuin kpl, poistaa kaikki alkion x esiintymät. * @param x poistettava alkio. * @param kpl poistettavien määrä. * @return poistettujen määrä */ int poista(E x, int kpl); /** * Poistaa alkion x kaikki esiintymät. * @param x poistettava alkio * @return poistettujen määrä */ default int poistaKaikki(E x) { return poista(x, Integer.MAX_VALUE); } /** * Sisältääkö laukku vähintään yhden kappaleen alkiota x. * @param x tarkasteltava alkio. * @return true jos alkio on laukussa, muuten false. */ default boolean sisaltaa(E x) { return (luku(x) > 0); } /** * Montako alkion x esiintymää on laukussa x? * @param x tarkasteltava alkio. * @return ko alkioiden määrä, 0 jollei esiinny lainkaan. */ int luku(E x); /** * Kaikkien alkioiden yhteismäärä laukussa. * Jos laukussa on alkiot [ a a b ] luku on 3. * @return alkioiden määrä. */ int koko(); /** * Muodostaa uuden laukun jossa on samat alkiot. * Samat alkiot ja kutakin yhtä monta kuin tässä kokoelmassa. * @return uusi laukku */ Laukku kopio(); /** * Lisää tähän laukkuun kaikki laukun L alkiot huomioiden * kunkin alkion esiintymismäärät. Tässä laukussa ollet alkiot * säilyvät. Jos jokin alkio x on molemmissa laukuissa, tähän laukkuun * tulee sitä yhteismäärän mukainen määrä. * @param L lisättävät alkiot * @return true jos alkioita lisättiin */ boolean lisaaKaikki(Laukku L); /** * Poistaa tästä laukusta kaikki laukun L alkiot huomioiden * kunkin alkion esiintymismäärät. * Jos tässä laukussa on n kpl elementtiä x ja laukussa L on m kpl, niin: * jos n <= m: poistaa kaikki x:n esiintymät, * jos n > m: x:ää jää jäljelle n-m kpl. * @param L poistettavat alkiot * @return poistettujen kokonaismäärä */ int poistaKaikki(Laukku L); /** * Säilyttää tästä laukusta kaikki laukun L alkiot huomioiden * kunkin alkion esiintymismäärät. * Jos tässä laukussa on n kpl elementtiä x ja laukussa L on m kpl, niin: * jos m == 0, niin poistaa kaikki x:n esiintymät. * jos m < n, niin jäljelle jää m kpl (poistetaan n-m) * jos m >= n: ei poisteta mitään * @param L säilytettävät alkiot * @return poistettujen kokonaismäärä */ int sailytaKaikki(Laukku L); /** * Tarkastelee onko tässä laukussa kaikki laukun L alkiot huomioiden * kunkin alkion esiintymismäärät. * Jotta palautetaan tosi, on jokaista tämän laukun alkiota oltava vähintään * yhtä monta kappaletta kuin laukussa L on kyseistä alkiota. * @param L vertailtava laukku * @return true jos kaikki L:n alkiot löytyvät tästä laukusta, muuten false */ boolean sisaltaaKaikki(Laukku L); /** * Sisältääkö tämä laukku samat alkiot samoissa määrissä kuin laukku L. * @param L vertailulaukku * @return true jos samat alkiot, muuten epätosi */ default boolean samatSisallot(Laukku L) { return sisaltaaKaikki(L) && L.sisaltaaKaikki(this); } /** * Tyhjentää laukun sisällön. */ void tyhjenna(); /** * Palauttaa iteraattorin jolla voidaan käydä läpi laukun kaikki alkiot. * Kunkin alkion kukin esiintymä palautetaan erikseen. * @return uusi iteraattori */ Iterator iterator(); /** * Läpikäynti pareille jossa kussakin parissa on alkio ja sen esiintymismäärä. * Tämä on erityisen näppärä testaukseen ja usean laukun operaatioihin. * @return läpikäynti */ Iterable> alkioMaarat(); }