Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Osan kaikki tehtävät

huomautus

Jos palautat tehtävät ennen osion takarajaa (ma 9.2.2026 klo 11:59 (keskipäivä)), voit saada DL-BONUS-pisteitä harjoitustehtäviin. Lue lisää suorittaminen-sivulta.

Tehtävä 4.1: Muunnin. 1 p.
  1. Luo rajapinta nimeltään Muunnin. Määrittele rajapintaan yksi metodi: String muunna(String syote). Muista, että rajapinnassa metodilla ei ole runkoa (ei aaltosulkeita {}).

  2. Tee luokat PienetKirjaimet, IsotKirjaimet ja IsoAlkukirjain, jotka toteuttavat Muunnin-rajapinnan.

  • PienetKirjaimet-luokan muunna-metodi muuntaa annetun merkkijonon pieniksi kirjaimiksi. muunna("Hei Maa") --> "hei maa".
  • IsotKirjaimet-luokan muunna-metodi muuntaa annetun merkkijonon suuraakkosiksi. muunna("Hei Maa") --> "HEI MAA".
  • IsoAlkukirjain-luokan muunna-metodi muuntaa annetun merkkijonon siten, että vain ensimmäinen kirjain on suuraakkonen ja muut pieniä. muunna("HEI MAA") --> "Hei maa".
  1. Testaa ohjelmaasi valmiiksi annetulla pääohjelmalla.
Tee tehtävä TIMissä
Tehtävä 4.2: Vakoojien viestijärjestelmä.1 p.

Vakoojat lähettävät viestejä toisilleen, mutta salausmenetelmä vaihtuu päivittäin, jotta vihollinen ei pääse perille logiikasta. Tarvitsemme rajapinnan, jonka avulla voimme vaihtaa salausalgoritmia lennosta.

  1. Luo rajapinta Salaaja. Määrittele rajapintaan kaksi metodia
String salaa(String viesti);
String pura(String salattuViesti);
  1. Toteuta kolme erilaista luokkaa: Kaantaja, Hakkeri ja SeuraavaKirjain, jotka toteuttavat Salaaja-rajapinnan seuraavilla logiikoilla:
  • Kaantaja (Peilikuvakirjoitus). Kääntää sanan väärinpäin. Esimerkki: "Agentti" → "ittnegA". Vihje: Voit käyttää StringBuilder-luokan reverse()-komentoa tai silmukkaa, joka käy sanan läpi lopusta alkuun.

  • Hakkeri ("Leet-speak"). Korvaa tietyt kirjaimet numeroilla tai merkeillä. Esimerkki: "Agentti" -> "@g3ntt!"

Korvaa 'a' -> '@'
Korvaa 'e' -> '3'
Korvaa 'i' -> '!'
Korvaa 'o' -> '0'
  • SeuraavaKirjain (Caesar-siirros). Jokaista kirjainta siirretään aakkosissa yksi eteenpäin. Esimerkki: abc -> bcd. Vihje: Javassa char on luku. Voit tehdä merkki + 1.
'a' -> 'b'
'b' -> 'c'
'k' -> 'l'
jne. 

Tässä harjoituksessa ei tarvitse huolehtia ö-kirjaimen pyörähtämisestä ympäri, ellei halua. Tehtävässä ei myöskään tarvitse huolehtia siitä, että salauksen ja purkamisen jälkeen saatu viesti ei välttämättä ole samanlainen kuin alkuperäinen viesti. Esimerkiksi jos Hakkeri-muuntajaa käytettäessä alkuperäisessä viestissä on oikeasti merkki @, pura-metodi antaa tulokseksi tuohon paikalle merkin a. Tämä ei haittaa tässä, mutta tietenkin oikeassa salauksessa pitäisi varmistaa, ettei tietoa katoa tai muutu vahingossa.

Saat TIMissä valmiina pääohjelman, jonka avulla voit testata luokkarakennettasi.

Tee tehtävä TIMissä
Tehtävä 4.3: Seikkailupeli. 1 p.

Toteutetaan yksinkertainen tekstiseikkailupeli (tai oikeammin pieni palanen pelistä), jossa pelaaja voi yrittää poimia esineitä maasta, sekä syödä saadakseen energiaa. Saat valmiina kaksi rajapintaa: Syotava ja Poimittava. Lisäksi saat osittain toteutetut luokat: Omena ja IsoKivi, jotka toteuttavat nämä rajapinnat. Edelleen, saat osittain toteutetun pääohjelman, jossa pelaajan energiaa ja repun tilaa seurataan.

Täydennä kaikki TODO-sanalla merkityt osat, jotta ohjelma toimii ohjeiden mukaisesti.

Tee tehtävä TIMissä
Bonus: Tehtävä 4.4: Kotityörobotti. 1 p.

Tee Robotti, joka osaa suorittaa erilaisia kotitöitä, kuten imurointia ja kukkien kastelua.

Toteuta tehtävä oheisen UML-kaavion mukaisesti. Katkoviiva, jossa on musta nuoli, tarkoittaa, että Robotti-luokka käyttää KayttoEsine-rajapintaa: Robotti-luokka sisältää attribuutin, joka on tyyppiä KayttoEsine.

Kuvaus sanallisessa muodossa

Tässä on kuvaus luokista ja niiden vaadituista ominaisuuksista (vastaavat kuin UML-kaaviossa):

Robotilla on seuraavat metodit:

  • void vaihdaKayttoEsine(KayttoEsine esine): Vaihtaa robotin käyttämän esineen (esim. imuri tai kastelukannu).
  • void teeTyota(String kohde): Suorittaa kotityön. Jos kohde on sillä listalla, jotka kyseiseltä käyttöesineeltä on kielletty (esim. Kastelukannu-oliolla ei saa kastella "Tietokone"-kohdetta), robotin tulee tulostaa virheilmoitus. Kielletyt käyttökohteet määritellään käyttöesineen attribuuttina merkkijonolistana.
  • Kastelukannu-olio ei kastele jos vettä ei ole riittävästi. Sen voi täyttää taytaVesi()-metodilla. Kastelukannun vesimäärä on aluksi 50 yksikköä. Voit halutessasi tehdä uuden muodostajan, joka asettaa vesimäärän alkutilan toiseksi.
  • Imuri-olio ei imuroi jos roskasäiliö on täynnä. Sen voi tyhjentää tyhjennaSailio()-metodilla. Roskasäiliön kapasiteetti on 100 yksikköä. Voit halutessasi tehdä uuden muodostajan, joka asettaa roskasäiliön alkutilan toiseksi.
  • Molemmat käyttöesineet palauttavat kayta(String kohde)-metodin avulla totuusarvon, joka kertoo onnistuiko työ.
Tee tehtävä TIMissä
Tehtävä 4.5: Miksi Comparable. 1 p.

Tutki Javan dokumentaatiota. Vastaa kysymyksiin Comparable-rajapinnasta.

Tee tehtävä TIMissä
Tehtävä 4.6: Henkilöt järjestykseen, osa 1. 1 p.

Tehtävässä on pohjana Henkilo-luokka omassa tiedostossaan sekä jarjestaHenkilot-metodi main.java-tiedostossa. Kyseinen metodi ei kuitenkaan toimi, sillä se käyttää Javan valmista Collections.sort-metodia ja Henkilo-luokasta puuttuu sille tuki.

Muokkaa Henkilo-luokkaa niin, että List<Henkilo>-tyyppiset listat voidaan järjestää Collections.sort-metodilla henkilön nimen mukaan aakkosjärjestykseen.

Esimerkiksi listan

List<Henkilo> henkilot = Arrays.asList(
    new Henkilo("Joukahainen"),
    new Henkilo("Ilmatar"),
    new Henkilo("Kyllikki"),
    new Henkilo("Kokko")
);

pitäisi olla Collections.sort(henkilot);-kutsun jälkeen järjestyksessä:

  1. Ilmatar
  2. Joukahainen
  3. Kokko
  4. Kyllikki
Tee tehtävä TIMissä
Tehtävä 4.7: Henkilöt järjestykseen, osa 2. 1 p.

Jatkoa edelliselle tehtävälle. Nyt Henkilo-luokassa henkilöiden nimet on jaettu erikseen sukunimeen ja etunimiin.

Muokkaa uudistettua Henkilo-luokkaa niin, että List<Henkilo>-tyyppiset listat voidaan järjestää Collections.sort-metodilla henkilön sukunimen ja etunimien mukaan aakkosjärjestykseen, niin että järjestys tapahtuu ensin sukunimen mukaan.

Esimerkiksi listan

List<Henkilo> henkilot = Arrays.asList(
        new Henkilo("Pacius", "Fredrik"),
        new Henkilo("Mozart", "Wolfgang Amadeus"),
        new Henkilo("Mozart", "Leopold"),
        new Henkilo("Chopin", "Frédéric")
);

pitäisi olla Collections.sort(henkilot);-kutsun jälkeen järjestyksessä:

  1. Chopin Frédéric
  2. Mozart Leopold
  3. Mozart Wolfgang Amadeus
  4. Pacius Fredrik
Tee tehtävä TIMissä
Tehtävä 4.8: Etsi suurin. 1 p.

Tee geneerinen metodi etsiSuurin, joka etsii listan suurimman alkion. Parametrina tulevan listan tulee toteuttaa Comparable-rajapinta, muutoin lista voi olla minkä tyyppinen tahansa. Älä käytä valmiita Collections-luokan metodeja.

Tee tehtävä TIMissä
Tehtävä 4.9: Kontti. 1 p.

Tee luokka Kontti, joka hyödyntää geneerisyyttä ja toimii yksinkertaisena säiliönä yhdelle minkä tahansa tyypin oliolle.

Lisää luokkaan attribuutti sisalto, joka voi sisältää minkä tahansa tyyppisen olion. Lisää myös merkkijono omistaja. Tee luokkaan muodostaja, joka ottaa nämä arvot vastaan parametreina.

Lisää lisäksi saantimetodit getOmistaja, getSisalto ja getTyyppi, joista viimeinen palauttaa kontin sisällön tyypin merkkijonona. Tee myös override toString-metodille, joka palauttaa nämä tiedot yhdessä merkkijonossa.

Tehtävässä on valmiiksi pääohjelma, jolla voit kokeilla luokan toimintaa.

Vinkki

Olion tyypin saa merkkijonona metodilla olio.getClass().getSimpleName().

Tee tehtävä TIMissä
Bonus: Tehtävä 4.10: Iso kontti. 1 p.

Luo luokka IsoKontti, joka toimii säiliönä usealle minkä tahansa tyypin oliolle. Konttiin pakataan esineitä niin, että viimeisimpänä lisätty otetaan aina ensimmäiseksi pois.

Lisää luokkaan attribuutiksi lista, johon oliot tallennetaan.

Lisää myös seuraavat metodit:

  • lisaa lisää parametrina annetun olion listan loppuun.

  • ota palauttaa viimeisimmän olion ja ottaa sen pois listasta.

  • katso palauttaa viimeisimmän olion, mutta ei ota sitä pois listasta.

  • sisaltaa ottaa parametrina olion ja palauttaa true, jos olio löytyy kontista. Muussa tapauksessa se palauttaa false.

  • tulosta tulostaa kontin sisällön. Voit itse päättää, missä muodossa sisältö tulostetaan.

Tehtävässä on valmiiksi pääohjelma, jolla voit kokeilla luokan toimintaa.

Tee tehtävä TIMissä
Bonus: Tehtävä 4.11: Tyyppirajoitukset, osa 1. 1 p.

Lisää edellisen tehtävän IsoKontti-luokkaan kaksi metodia.

  1. Metodi summaaNumerot ottaa parametrina vastaan kontin, joka sisältää numeroita eli Number-luokan tai sen alityyppien olioita ja palauttaa näiden summan.

  2. Metodi siirraKaikki ottaa parametrina toisen kontin ja siirtää nykyisen kontin sisällön sinne. Toisen kontin täytyy olla tyypiltään sellainen, että se voi sisältää tämän kontin tyypin olioita.

Tehtävässä on valmiiksi pääohjelma, jolla voit kokeilla luokan toimintaa.

Vinkki

Tarvitset tässä tehtävässä tyyppirajoituksia.

  1. Kaikilla Number-luokan olioilla on doubleValue()-metodi, joka palauttaa sen arvon double-muodossa.

  2. Huomaa, että konttien tyyppien ei tarvitse olla täysin samat; Number-kontti voi sisältää Integer-olioita, sillä Integer on sen alityyppi.

Tee tehtävä TIMissä
Bonus: Tehtävä 4.12: Tyyppirajoitukset, osa 2. 1 p.

Tee geneerinen funktio, joka kopioi yhdestä listasta kaikki tyyppiä T vastaavat alkiot toiseen listaan, jonka tyyppi voi olla T tai sen ylityyppi.

Tee tehtävä TIMissä