Olioita listalla ja listan sisältävät oliot
Tutustutaan seuraavaksi olioihin, jonka sisältävät listan. Tällaisia olioita ovat esimerkiksi joukkoja kuvaavat oliot, kuten vaikkapa soittolistat.
Alla olevassa esimerkissä käsitteelle soittolista on luotu luokka. Soittolista sisältää kappaleita: siihen voi lisätä kappaleita, siitä voi poistaa kappaleita, ja siinä olevat kappaleet voi tulostaa.
// importit
public class Soittolista {
private ArrayList<String> kappaleet;
public Soittolista() {
this.kappaleet = new ArrayList<>();
}
public void lisaaKappale(String kappale) {
this.kappaleet.add(kappale);
}
public void poistaKappale(String kappale) {
this.kappaleet.remove(kappale);
}
public void tulostaKappaleet() {
for (String kappale: this.kappaleet) {
System.out.println(kappale);
}
}
}
Soittolistojen luominen on edellisen luokan avulla helppoa.
Soittolista lista = new Soittolista();
lista.lisaaKappale("Sorateiden kuningas");
lista.lisaaKappale("Teuvo, maanteiden kuningas");
lista.tulostaKappaleet();
Sorateiden kuningas Teuvo, maanteiden kuningas
Omia olioita oliomuuttujana olevalla listalla
Oliomuuttujana oleva lista voi sisältää merkkijonojen lisäksi myös muunlaisia olioita, kunhan listalla olevien olioiden tyyppi määritellään listan määrittelyn yhteydessä.
Loimme edellisessä osassa luokan Huvipuistolaite
, jonka avulla tarkastellaan pääseekö henkilö laitteen kyytiin. Luokka Huvipuistolaite
näyttää seuraavalta.
public class Huvipuistolaite {
private String nimi;
private int alinPituus;
private int kavijoita;
public Huvipuistolaite(String nimi, int alinPituus) {
this.nimi = nimi;
this.alinPituus = alinPituus;
this.kavijoita = 0;
}
public boolean paaseeKyytiin(Henkilo henkilo) {
if (henkilo.getPituus() < this.alinPituus) {
return false;
}
this.kavijoita++;
return true;
}
public String toString() {
return this.nimi + ", pituusalaraja: " + this.alinPituus +
", kävijöitä: " + this.kavijoita;
}
}
Laajennetaan luokkaa siten, että huvipuistolaite pitää kirjaa kyydissä olevista henkilöistä. Laajennetussa versiossa huvipuistolaitteella on oliomuuttujana lista, joka sisältää laitteeseen päässeet henkilöt. Lista luodaan konstruktorissa.
public class Huvipuistolaite {
private String nimi;
private int alinPituus;
private int kavijoita;
private ArrayList<Henkilo> kyydissa;
public Huvipuistolaite(String nimi, int alinPituus) {
this.nimi = nimi;
this.alinPituus = alinPituus;
this.kavijoita = 0;
this.kyydissa = new ArrayList<>();
}
// ..
}
Muokataan seuraavaksi metodia paaseeKyytiin
. Metodi lisää listalle ne henkilöt, jotka ovat tarpeeksi pitkiä.
public class Huvipuistolaite {
private String nimi;
private int alinPituus;
private int kavijoita;
private ArrayList<Henkilo> kyydissa;
public Huvipuistolaite(String nimi, int alinPituus) {
this.nimi = nimi;
this.alinPituus = alinPituus;
this.kavijoita = 0;
this.kyydissa = new ArrayList<>();
}
public boolean paaseeKyytiin(Henkilo henkilo) {
if (henkilo.getPituus() < this.alinPituus) {
return false;
}
this.kavijoita++;
this.kyydissa.add(henkilo);
return true;
}
public String toString() {
return this.nimi + ", pituusalaraja: " + this.alinPituus +
", kävijöitä: " + this.kavijoita;
}
}
Listan sisältävän olion tulostaminen
Muokataan seuraavaksi metodia toString
siten, että metodin palauttama merkkijono sisältää jokaisen kyydissä olevan henkilön nimen.
public class Huvipuistolaite {
private String nimi;
private int alinPituus;
private int kavijoita;
private ArrayList<Henkilo> kyydissa;
// ...
public String toString() {
// luodaan listalla olevista henkilöistä merkkijono
String kyydissaOlijat = "";
for (Henkilo henkilo: kyydissa) {
kyydissaOlijat = kyydissaOlijat + henkilo.getNimi() + "\n";
}
// palautetaan oliota kuvaava merkkijono,
// joka sisältää myös kyydissä olijat
return this.nimi + ", pituusalaraja: " + this.alinPituus +
", kävijöitä: " + this.kavijoita + "\n" +
"kyydissä:\n" + kyydissaOlijat;
}
}
Kokeillaan laajennettua huvipuistolaitetta:
Henkilo matti = new Henkilo("Matti");
matti.setPaino(86);
matti.setPituus(180);
Henkilo juhana = new Henkilo("Juhana");
juhana.setPaino(34);
juhana.setPituus(132);
Huvipuistolaite hurjakuru = new Huvipuistolaite("Hurjakuru", 140);
System.out.println(hurjakuru);
System.out.println();
if (hurjakuru.paaseeKyytiin(matti)) {
System.out.println(matti.getNimi() + " pääsee laitteeseen");
} else {
System.out.println(matti.getNimi() + " ei pääse laitteeseen");
}
if (hurjakuru.paaseeKyytiin(juhana)) {
System.out.println(juhana.getNimi() + " pääsee laitteeseen");
} else {
System.out.println(juhana.getNimi() + " ei pääse laitteeseen");
}
System.out.println(hurjakuru);
Ohjelma tulostaa:
Hurjakuru, pituusalaraja: 140, kävijöitä: 0 kyydissä:
Matti pääsee laitteeseen Juhana ei pääse laitteeseen Hurjakuru, pituusalaraja: 140, kävijöitä: 1 kyydissä: Matti
Vaikka laitteessa ei ole ketään kyydissä, on tulostuksessa silti merkkijono kyydissä:
. Muokataan metodia toString
siten, että jos kyydissä ei ole ketään, metodi palauttamassa merkkijonossa on tieto siitä.
public class Huvipuistolaite {
private String nimi;
private int alinPituus;
private int kavijoita;
private ArrayList<Henkilo> kyydissa;
public Huvipuistolaite(String nimi, int alinPituus) {
this.nimi = nimi;
this.alinPituus = alinPituus;
this.kavijoita = 0;
this.kyydissa = new ArrayList<>();
}
// ...
public String toString() {
String tulostus = this.nimi + ", pituusalaraja: " + this.alinPituus +
", kävijöitä: " + this.kavijoita + "\n";
if (kyydissa.isEmpty()) {
return tulostus + "ei ketään kyydissä.";
}
// luodaan listalla olevista henkilöistä merkkijono
String kyydissaOlijat = "";
for (Henkilo henkilo: kyydissa) {
kyydissaOlijat = kyydissaOlijat + henkilo.getNimi() + "\n";
}
return tulostus + "\n" +
"kyydissä:\n" + kyydissaOlijat;
}
}
Nyt olion tulostus on parempi.
Henkilo matti = new Henkilo("Matti");
matti.setPaino(86);
matti.setPituus(180);
Henkilo juhana = new Henkilo("Juhana");
juhana.setPaino(34);
juhana.setPituus(132);
Huvipuistolaite hurjakuru = new Huvipuistolaite("Hurjakuru", 140);
System.out.println(hurjakuru);
System.out.println();
if (hurjakuru.paaseeKyytiin(matti)) {
System.out.println(matti.getNimi() + " pääsee laitteeseen");
} else {
System.out.println(matti.getNimi() + " ei pääse laitteeseen");
}
if (hurjakuru.paaseeKyytiin(juhana)) {
System.out.println(juhana.getNimi() + " pääsee laitteeseen");
} else {
System.out.println(juhana.getNimi() + " ei pääse laitteeseen");
}
System.out.println(hurjakuru);
Ohjelma tulostaa:
Hurjakuru, pituusalaraja: 140, kävijöitä: 0 ei ketään kyydissä.
Matti pääsee laitteeseen Juhana ei pääse laitteeseen Hurjakuru, pituusalaraja: 140, kävijöitä: 1 kyydissä: Matti
Olion sisältämän listan tyhjentäminen
Lisätään huvipuistolaitteelle seuraavaksi metodi poistaKaikkiKyydista
, joka poistaa kaikki laitteessa olevat henkilöt laitteen kyydistä. Tässä listan metodi clear
on erittäin kätevä.
public class Huvipuistolaite {
// ..
public void poistaKaikkiKyydista() {
this.kyydissa.clear();
}
// ..
}
Henkilo matti = new Henkilo("Matti");
matti.setPaino(86);
matti.setPituus(180);
Henkilo juhana = new Henkilo("Juhana");
juhana.setPaino(34);
juhana.setPituus(132);
Huvipuistolaite hurjakuru = new Huvipuistolaite("Hurjakuru", 140);
System.out.println(hurjakuru);
System.out.println();
if (hurjakuru.paaseeKyytiin(matti)) {
System.out.println(matti.getNimi() + " pääsee laitteeseen");
} else {
System.out.println(matti.getNimi() + " ei pääse laitteeseen");
}
if (hurjakuru.paaseeKyytiin(juhana)) {
System.out.println(juhana.getNimi() + " pääsee laitteeseen");
} else {
System.out.println(juhana.getNimi() + " ei pääse laitteeseen");
}
System.out.println(hurjakuru);
hurjakuru.poistaKaikkiKyydista();
System.out.println();
System.out.println(hurjakuru);
Ohjelma tulostaa:
Hurjakuru, pituusalaraja: 140, kävijöitä: 0 ei ketään kyydissä.
Matti pääsee laitteeseen Juhana ei pääse laitteeseen Hurjakuru, pituusalaraja: 140, kävijöitä: 1 kyydissä: Matti
Hurjakuru, pituusalaraja: 140, kävijöitä: 1 ei ketään kyydissä.
Yhteenvetoarvon laskeminen listalla olevista olioista
Tehdään huvipuistolaitteelle seuraavaksi metodi, joka laskee kyydissä olevien henkilöiden keskipituuden. Keskipituus saadaan laskemalla kyydissä olevien keskiarvo — keskiarvo laskettiin selvittämällä lukujen summa ja jakamalla summa lukujen määrällä.
Alla olevassa toteutuksessa palautetaan arvo -1
mikäli kyydissä ei ole yhtäkään henkilöä. Pituuksien keskiarvoa laskevassa ohjelmassa luku -1
on mahdoton, joten siitä voi päätellä ettei keskiarvoa ole voitu laskea.
public class Huvipuistolaite {
private String nimi;
private int alinPituus;
private int kavijoita;
private ArrayList<Henkilo> kyydissa;
// ..
public double kyydissaOlevienKeskipituus() {
if (kyydissa.isEmpty()) {
return -1;
}
int pituuksienSumma = 0;
for (Henkilo hlo: kyydissa) {
pituuksienSumma += hlo.getPituus();
}
return 1.0 * pituuksienSumma / kyydissa.size();
}
// ..
}
Henkilo matti = new Henkilo("Matti");
matti.setPituus(180);
Henkilo juhana = new Henkilo("Juhana");
juhana.setPituus(132);
Henkilo awak = new Henkilo("Awak");
awak.setPituus(194);
Huvipuistolaite hurjakuru = new Huvipuistolaite("Hurjakuru", 140);
hurjakuru.paaseeKyytiin(matti);
hurjakuru.paaseeKyytiin(juhana);
hurjakuru.paaseeKyytiin(awak);
System.out.println(hurjakuru);
System.out.println(hurjakuru.kyydissaOlevienKeskipituus());
Ohjelma tulostaa:
Hurjakuru, pituusalaraja: 140, kävijöitä: 2 kyydissä: Matti Awak 187.0
Tietyn olion hakeminen listalta
Tehdään seuraavaksi huvipuistolaitteelle metodi, joka palauttaa laitteen kyydissä olevista henkilöistä pisimmän. Metodin tulee siis sekä hakea listalta pisin henkilö, että palauttaa se.
Metodit, jotka hakevat listalta oliota, kannattaa toteuttaa seuraavasti. Ensin katsotaan onko lista tyhjä — mikäli lista on tyhjä, palautetaan null
-viite tai joku muu arvo, joka kertoo että listalla ei ollut arvoja. Tämän jälkeen luodaan palautettavaa oliota kuvaava oliomuuttuja, jonka arvoksi asetetaan listan ensimmäinen olio. Tätä seuraa listan arvojen läpikäynti siten, että kutakin listalla olevaa oliota verrataan palautettavaa oliota kuvaavaan oliomuuttujaan. Mikäli vertailussa löydetään hakuun paremmin osuva olio, asetetaan palautettavan olion arvoksi hakuun paremmin osuva olio. Lopulta palautettavaa oliota kuvaava oliomuuttuja palautetaan.
public Henkilo haePisin() {
// jos kyydissä ei ole ketään, palauta null-viite
if (this.kyydissa.isEmpty()) {
return null;
}
// luo palautettavaa oliota kuvaava oliomuuttuja,
// jonka arvoksi asetetaan listan ensimmäinen olio
Henkilo palautettava = this.kyydissa.get(0);
// käy lista läpi
for (Henkilo hlo: this.kyydissa) {
// vertaa kutakin listalla olevaa oliota
// palautettavaan -- tässä etsimme pisintä, joten
// vertailemme pituuksia
if (palautettava.getPituus() < hlo.getPituus()) {
// mikäli vertailussa löydetään pidempi henkilö,
// asetetaan se palautettavan arvoksi
palautettava = hlo;
}
}
// lopulta palautettavaa oliota kuvaava oliomuuttuja
// palautetaan
return palautettava;
}
Nyt pisimmän henkilön löytäminen on helppoa.
Henkilo matti = new Henkilo("Matti");
matti.setPituus(180);
Henkilo juhana = new Henkilo("Juhana");
juhana.setPituus(132);
Henkilo awak = new Henkilo("Awak");
awak.setPituus(194);
Huvipuistolaite hurjakuru = new Huvipuistolaite("Hurjakuru", 140);
hurjakuru.paaseeKyytiin(matti);
hurjakuru.paaseeKyytiin(juhana);
hurjakuru.paaseeKyytiin(awak);
System.out.println(hurjakuru);
System.out.println(hurjakuru.kyydissaOlevienKeskipituus());
System.out.println();
System.out.println(hurjakuru.haePisin().getNimi());
Henkilo pisin = hurjakuru.haePisin();
System.out.println(pisin.getNimi());
Hurjakuru, pituusalaraja: 140, kävijöitä: 2 kyydissä: Matti Awak 187.0
Awak Awak
Muistathan tarkistaa pistetilanteesi materiaalin oikeassa alareunassa olevasta pallosta!