Osan kaikki tehtävät
huomautus
Jos palautat tehtävät ennen osan takarajaa (ma 23.2.2026 klo 11:59 (keskipäivä)), voit saada DL-BONUS-pisteitä harjoitustehtäviin. Lue lisää suorittaminen-sivulta.
Tee ohjelma, joka kysyy käyttäjältä kaksi desimaalilukua sekä laskutoimituksen ja tulostaa lopputuloksen seuraavasti:
Luku 1 > 12.0
Luku 2 > 3.0
Laskutoimitus (+, -, *, /) > +
12.0 + 3.0 = 15.0
Tässä vaiheessa sinun ei tarvitse käsitellä virheellisiä syötteitä, vaan voit
olettaa, että luvut annetaan aina lukuina. Sallitut laskutoimitukset ovat summa
(+), erotus (-), tulo (*) ja osamäärä (/). Voit olettaa, että vain näitä
laskutoimituksia käytetään syötteenä.
Älä käytä silmukoita tai ehtorakenteita. Sen sijaan toteuta laskutoimitukset lambdalausekkeina ja tallenna ne hakurakenteeseen käyttäen laskutoimituksen merkkiä avaimena.
Ohjelman suoritus päättyy tuloksen näyttämisen jälkeen.
Vinkki 1
Voit käyttää lambdalausekkeiden tyyppinä BiFunction<Double, Double, Double>
(JavaDoc)
tai DoubleBinaryOperator
(JavaDoc).
Vinkki 2
Voit käyttää hakurakenteen tyyppinä Map<String, BiFunction<Double, Double, Double>> tai Map<String, DoubleBinaryOperator>.
Voit joko valita hakurakenteelle tietyn toteutuksen tai alustaa muuttumattoman
hakurakenteen Map.of-metodilla:
Map<String, BiFunction<Double, Double, Double>> laskutoimitukset = Map.of(
"+", ...,
"-", ...,
"*", ...,
"/", ...
);
...-kohdan tilalle riittää asettaa sopiva lambdalauseke.
Laajenna Kerailykortti-luokkaa
lisäämällä sille attribuutti String harvinaisuus. Keräilykortin harvinaisuus voi olla yksi seuraavista arvoista
(vähiten harvinaisesta harvinaisimpaan): C, U, R, RR, RRR, SR, AR,
SAR, UR.
Kirjoita vertailija, joka järjestää listassa olevat kortit niiden harvinaisuuden mukaan. Voit käyttää seuraavaa valmista korttikokoelmaa koodisi testaamiseen:
Mallilista erilaisista korteista
List<Kerailykortti> kortit = new ArrayList<>(List.of(
new Kerailykortti("Kadonnut Puolipiste", "Koodiviidakko", 101, "C"),
new Kerailykortti("Loputon Silmukka", "Koodiviidakko", 102, "U"),
new Kerailykortti("Bugimetsästäjä", "Koodiviidakko", 103, "R"),
new Kerailykortti("Spagettikoodi-Hirviö", "Koodiviidakko", 104, "RR"),
new Kerailykortti("Ylikellotettu Prosessori", "Koodiviidakko", 105, "SR"),
new Kerailykortti("Pyhä Stack Overflow", "Koodiviidakko", 106, "RRR"),
new Kerailykortti("Null Pointer -Ninja", "Koodiviidakko", 107, "U"),
new Kerailykortti("Sininen Kuolemanruutu", "Koodiviidakko", 108, "AR"),
new Kerailykortti("Opiskelijakortti", "Kampus-Saaga", 201, "C"),
new Kerailykortti("Unelias Luennoitsija", "Kampus-Saaga", 202, "C"),
new Kerailykortti("Haalaribileet", "Kampus-Saaga", 203, "U"),
new Kerailykortti("Ylisuorittaja", "Kampus-Saaga", 204, "R"),
new Kerailykortti("Ilmainen Ämpäri", "Kampus-Saaga", 205, "SAR"),
new Kerailykortti("Myöhästynyt Palautus", "Kampus-Saaga", 206, "RR"),
new Kerailykortti("Akateeminen Vartti", "Kampus-Saaga", 207, "SR"),
new Kerailykortti("Gradu-Ahdistus", "Kampus-Saaga", 208, "AR"),
new Kerailykortti("Semman Pannukakku", "Kampus-Saaga", 209, "UR"),
new Kerailykortti("Vihainen Hirvi", "Suomi-Myytit", 301, "C"),
new Kerailykortti("Ikuinen Marraskuu", "Suomi-Myytit", 302, "RR"),
new Kerailykortti("Saunaklonkku", "Suomi-Myytit", 303, "SR"),
new Kerailykortti("Salmiakkisade", "Suomi-Myytit", 304, "U"),
new Kerailykortti("Väinämöisen Kantele", "Suomi-Myytit", 305, "SAR"),
new Kerailykortti("Sisu", "Suomi-Myytit", 306, "RRR"),
new Kerailykortti("Laser-Löylykauha", "Suomi-Myytit", 307, "UR"),
new Kerailykortti("Toripoliisi", "Suomi-Myytit", 308, "R")
));
Kirjoita main()-ohjelma, joka järjestää ja tulostaa keräilykortit
harvinaisuuden mukaan (yleisimmät kortit ensin, harvinaisimmat viimeiseksi).
Kortit, joiden harvinaisuus on jokin muu kuin yllä mainitut tai null, tulee
sijoittaa listan alkuun.
Olkoon käytössä luokka Kappale, joka edustaa yksittäistä musiikkikappaletta.
Kappaleella on nimi, genre ja kesto sekunteina:
class Kappale {
String nimi;
String genre;
int kestoSekunteina;
}
Lisää luokalle tarvittavat näkyvyysmääreet, muodostaja, tarpeelliset
saantimetodit (getterit) sekä sopiva toString()-metodin toteutus.
Tee funktio teeSoittolista(kappaleet, genre, kappaleita), joka palauttaa
korkeintaan kappaleita-muuttujan ilmoittaman määrän kappaleita, joiden genre
vastaa annettua genre-parametria. Kappaleiden tulee olla järjestettynä keston
mukaan lyhyemmästä pisimpään.
Voit käyttää seuraavaa mallilistaa koodisi testaamiseen:
Lista mallikappaleista
List<Kappale> biisilista = List.of(
new Kappale("Bohemian Rhapsody", "Rock", 354),
new Kappale("Levitating", "Pop", 203),
new Kappale("Sandstorm", "Electronic", 225),
new Kappale("Paranoid", "Metal", 168),
new Kappale("Toxic", "Pop", 198),
new Kappale("Master of Puppets", "Metal", 515),
new Kappale("Cha Cha Cha", "Pop", 175),
new Kappale("Hotel California", "Rock", 390),
new Kappale("Stay", "Pop", 141),
new Kappale("Enter Sandman", "Metal", 331),
new Kappale("Bad Romance", "Pop", 295),
new Kappale("Midnight City", "Electronic", 243),
new Kappale("Billie Jean", "Pop", 294),
new Kappale("Hard Rock Hallelujah", "Metal", 247),
new Kappale("Thriller", "Pop", 357),
new Kappale("As It Was", "Pop", 167),
new Kappale("Paint It, Black", "Rock", 202),
new Kappale("Hollywood Hills", "Rock", 210),
new Kappale("Get Lucky", "Electronic", 369),
new Kappale("Shake It Off", "Pop", 219),
new Kappale("Ace of Spades", "Metal", 169),
new Kappale("Rolling in the Deep", "Pop", 228),
new Kappale("Sweet Child O' Mine", "Rock", 356),
new Kappale("Borderline", "Pop", 210),
new Kappale("Back in Black", "Rock", 255),
new Kappale("Shape of You", "Pop", 233),
new Kappale("Fear of the Dark", "Metal", 438),
new Kappale("Blinding Lights", "Pop", 200),
new Kappale("Stairway to Heaven", "Rock", 482),
new Kappale("Uptown Funk", "Pop", 269),
new Kappale("Smells Like Teen Spirit", "Rock", 301),
new Kappale("Short Pop Song", "Pop", 120)
);
Älä käytä silmukoita, vaan toteuta teeSoittolista käyttäen striimejä.
Vinkki
Saatat tarvita ainakin seuraavia Stream-metodeja:
filter(): alkioiden suodatussorted(): alkioiden järjestäminenlimit(): alkioiden lukumäärän rajaaminentoList(): alkioiden kerääminen listaksi
Tee funktio double keskiarvo(int[] luvut, int minimi, int maksimi). Funktio
laskee taulukkona annettujen lukujen keskiarvon seuraavilla ehdoilla:
- Jos alkio on pienempi tai yhtä suuri kuin
minimi, alkio hylätään eikä sitä lasketa keskiarvoon mukaan. - Jos alkio on suurempi tai yhtä suuri kuin
maksimi, kyseinen alkio ja kaikki sen jälkeen tulevat alkiot hylätään.
Esimerkki:
IO.println(keskiarvo(new int[] { -5, 1, -4, 0, 98 }, -7, 99));
IO.println(keskiarvo(new int[] { 11, 4, 2, 6, 99, 12, 0, -3 }, 3, 99));
IO.println(keskiarvo(new int[] { 99, 1, 2, 3 }, 0, 99));
18.0
7.0
0.0
Ensimmäinen kutsu palauttaa 18.0, sillä aineisto on kokonaisuudessaan minimin
ja maksimin välissä. Toinen kutsu palauttaa taas 7.0, sillä vain luvut 11, 4
ja 6 otetaan keskiarvoon mukaan: luku 2 on pienempi kuin minimi ja kaikki
luvusta 99 alkaen hylätään.
Jos keskiarvoa ei voida laskea, funktio palauttaa minimi-parametrin arvon.
Älä käytä silmukoita, vaan toteuta funktio käyttäen striimejä.
Vinkki
Tutustu IntStream-tyyppiin
(JavaDoc)
ja sen metodeihin. Voit hyötyä ainakin seuraavista:
filter(): alkioiden suodattaminen pois striimistätakeWhile(): ottaa alkioita striimistä niin kauan kuin ehto on tosi; heti kun ehto on epätosi, striimin käsittely loppuu siihen (kuin "hana", joka suljetaan).average(): laskee keskiarvon
Huomaa, että average() palauttaa OptionalDouble-olion
(JavaDoc).
Olio sisältää orElse()-metodin, jonka avulla voit palauttaa joko lasketun
arvon tai vaihtoehtoisen oletusarvon.
Bonustieto
Samankaltainen tehtävä tehdään Ohjelmointi 1 -kurssilla käyttäen silmukoita (ks. Ohjelmointi 1: demo 6, tehtävä B1). Jos olet suorittanut kyseisen kurssin, voit verrata striimeillä tehtyä ratkaisuasi aiemmin tekemääsi silmukkaratkaisuun.
Tee monivalintatehtävä TIMissä.
Tee main, joka lukee käyttäjältä silmukassa kokonaislukuja niin kauan, kuin
käyttäjä antaa muun kuin tyhjän syötteen. Jos käyttäjä antaa muun kuin
kokonaisluvun, tulosta virheilmoitus ja jatka lukemista.
Tallenna luvut taulukkoon. Tulosta lopuksi kaikki taulukkoon tallennetut luvut.
Tee ohjelma, joka tarkistaa, onko käyttäjän syöttämä ikä riittävä tiettyyn toimintaan, esimerkiksi ajokortin hankkimiseen.
Tee aliohjelma onkoIkaa, joka ottaa parametrina iän (int) ja palauttaa
true, jos ikä on riittävä. Jos ikä on alle 18, heitä poikkeus IkaException,
joka on oma tarkastettu poikkeusluokka. Anna sopiva poikkeusviesti, esimerkiksi
"Ikä ei riitä.". Ohessa vinkiksi metodin esittelyrivi.
static boolean onkoIkaa(int ika) throws IkaException
Jos ikä on negatiivinen, heitä poikkeus IkaException viestillä "Ikä ei voi olla negatiivinen.".
Poista if-rakenne ja muokkaa main-metodia niin, että se kääntyy ja tulostaa
oikeat asiat.
Tee uusi Maven-projekti. Aseta pakkauksen nimeksi fi.jyu.omatunnus (laita
omatunnus-kohdalle JY-käyttäjätunnus tai jokin muu keksimäsi käyttäjänimi).
Anna pääluokan nimeksi Riippuvuudet. Lisää siihen tämä koodi.
void main() {
JSONObject json = new JSONObject();
json.put("nimi", "Maija");
json.put("ika", 25);
IO.println(json.getString("nimi"));
IO.println(json.getInt("ika"));
}
Lisää nyt pom.xml-tiedostoon riippuvuus json-nimiseen artefaktiin. Etsi tämä
kirjasto Maven Centralista, ja kopioi sieltä XML-koodi pom.xml-tiedostoosi.
Lisää myös riippuvuuden vaatima import-lause luokan alkuun.
Käännä ja aja ohjelma, ja varmista, että se tulostaa odotetut tiedot.
Lataa aineisto: sanat.txt
Tallenna tiedosto projektisi työskentelyhakemistoon nimellä sanat.txt.
Tiedostossa on yksi sana per rivi. Mukana on tarkoituksella tyhjiä rivejä, välilyöntejä sanojen alussa/lopussa, samoja sanoja useaan kertaan, eri kirjainkokoja (esim. Java, java, JAVA).
Esimerkki aineiston alusta:
Java
python
JAVA
CSharp
java
Tee ohjelma, joka:
- Lukee kaikki rivit.
- Poistaa sanoista ylimääräiset välilyönnit ja muuttaa sanat pieniksi
kirjaimiksi. Vinkki:
String.trim()jaString.toLowerCase(). - Poistaa tyhjät rivit.
- Poistaa duplikaatit. (Vinkki:
distinct()-metodi Stream API:lla, taiSet-kokoelma.) - Järjestää sanat aakkosjärjestykseen. (Vinkki:
sorted()-metodi Stream API:lla, taiCollections.sort()-metodi Listalla.) - Kirjoittaa uuden tiedoston
output/sanat-siisti.txt, jossa on siistitty sanalista (yksi sana per rivi). - Kirjoittaa lisäksi tiedoston
output/raportti.txt, jossa on:- alkuperäisten rivien määrä
- uniikkien sanojen määrä sen jälkeen, kun tyhjät rivit on poistettu ja sanat on siistitty
- pisin sana (jos useita, mikä tahansa kelpaa). Vinkki: Jos ratkaiset
tehtävän Stream API:lla, voit käyttää
Stream.max(Comparator)-metodia pisimmän sanan löytämiseen.
Vinkki: tee ensin List<String> siistit = ..., ja kirjoita lopuksi
Files.write(...) kahteen eri tiedostoon.
raportti.txt:n pitäisi näyttää tältä:
Alkuperäisiä rivejä: 1074
Siistittyjä sanoja: 59
Pisin sana: binarytree
EDIT 23.2.2026: Jackson-kirjaston riippuvuuksia ja esimerkkejä päivitetty materiaalissa. Pahoittelut virheistä.
- Tee uusi Maven-projekti, joka käyttää Jackson-kirjastoa JSON-tiedostojen käsittelyyn.
- Lisää
pom.xml-tiedostoosi tarvittava riippuvuus. - Lataa henkilot.json ja tallenna se projektiisi samaan kansioon kuin missä koodisi on.
Henkilo-luokka tai vastaava record, jolla on kentätString nimi,int ika,String kaupunki.- Lue tiedosto
henkilot.jsonja muuta se listaksiHenkilo-olioita. - Suodata mukaan vain vähintään 18-vuotiaat.
- Tulosta heidän nimensä, ikänsä ja kaupunkinsa.
Muista varmistaa, että tallennat henkilot.json-tiedoston samaan kansioon kuin
missä koodisi sijaitsee. Tarkista sitten ajokonfiguraatiostasi, että
työskentelyhakemisto on sama kuin koodisi kansio, jotta tiedosto löytyy.
Saat henkilöiden tiedot tarvittaessa auki tästä:
henkilot.json
[ { "nimi": "Maija Laine", "ika": 25, "kaupunki": "Jyväskylä" }, { "nimi": "Matti Virtanen", "ika": 30, "kaupunki": "Tampere" }, { "nimi": "Liisa Niemi", "ika": 17, "kaupunki": "Helsinki" }, { "nimi": "Pekka Korhonen", "ika": 41, "kaupunki": "Oulu" }, { "nimi": "Aino Salmi", "ika": 22, "kaupunki": "Turku" }, { "nimi": "Jari Heikkinen", "ika": 19, "kaupunki": "Kuopio" }, { "nimi": "Sari Lehto", "ika": 16, "kaupunki": "Lahti" }, { "nimi": "Oskari Mäkinen", "ika": 28, "kaupunki": "Espoo" }, { "nimi": "Emilia Ranta", "ika": 33, "kaupunki": "Vantaa" }, { "nimi": "Teemu Koski", "ika": 45, "kaupunki": "Pori" }, { "nimi": "Noora Aalto", "ika": 18, "kaupunki": "Joensuu" }, { "nimi": "Kalle Hämäläinen", "ika": 52, "kaupunki": "Rovaniemi" } ]
EDIT 23.2.2026: Jackson-kirjaston riippuvuuksia ja esimerkkejä päivitetty materiaalissa. Pahoittelut virheistä.
Tee ohjelma, joka lukee tiedoston
henkilot.csv
(muoto nimi,ika,kaupunki) ja kirjoittaa siitä saman tapainen JSON-tiedoston
henkilot.json kuin edellisessä tehtävässä oli annettu valmiiksi. Jos rivi on
virheellinen (esim. ikä ei ole numero), ohita rivi ja jatka käsittelyä.
Tulostiedoston pitäisi näyttää tältä. Ei haittaa, jos sisennykset tai rivinvaihdot eivät ole täsmälleen samanlaisia.
[
{
"nimi": "Maija Laine",
"ika": 25,
"kaupunki": "Jyväskylä"
},
{
"nimi": "Matti Virtanen",
"ika": 30,
"kaupunki": "Tampere"
},
...
]
Tee yksinkertainen laskinohjelma, joka kysyy käyttäjältä toistuvasti kaksi lukua sekä laskutoimituksen ja tulostaa laskutoimituksen tuloksen.
Ohjelman tulisi toimia suunnilleen seuraavasti:
Anna laskutoimitus muodossa <luku> <operaattori> <luku>.
Kirjoita "sulje" sulkeaksesi ohjelman.
> 1 + 1
2.0
> 10 - 1
9.0
> 0.5 * 100
50.0
> 10 / 2
5.0
> 10
Anna laskutoimitus muodossa <luku> <operaattori> <luku>.
> kissa
Anna laskutoimitus muodossa <luku> <operaattori> <luku>.
> sulje
Ohjelma sulkeutuu.
Ohjelman on käsiteltävä käyttäjän syötteessä olevat virheet siten, ettei ohjelma kaadu virheellisen syötteen vuoksi.
Toteuta peruslaskutoimituksista summa (+), erotus (-), tulo (*) ja
osamäärä (/). Keksi lisäksi vähintään kaksi omaa vapaavalintaista
laskutoimitusta ja toteuta ne.
Älä käytä ehtorakenteita varsinaisten laskutoimitusten valitsemiseen. Voit
kuitenkin käyttää ehtorakenteita sekä try/catch-rakenteita syötteen
oikeellisuuden tarkistamiseen.
Vinkki 1
Voit toteuttaa operaatiot lambdalausekkeina. Käytä lambdalausekkeiden tyyppinä
BiFunction<Double, Double, Double>
(JavaDoc)
tai DoubleBinaryOperator
(JavaDoc).
Vinkki 2
Voit käyttää Scanner-luokkaa käyttäjän syötteen lukemiseen:
Scanner lukija = new Scanner(kayttajanSyote);
double luku1 = lukija.nextDouble();
String laskutoimitus = lukija.next();
double luku2 = lukija.nextDouble();
Saatat joutua lisäämään tarvittavat poikkeustenkäsittelyt.