Osa 3

Merkkijonojen käsittely

Kerrataan seuraavaksi merkkijonoihin liittyviä perusominaisuuksia ja tutustutaan niiden pilkkomiseen. Alla luodaan merkkijonomuuttuja taikasana, joka sisältää arvon "abrakadabra".

String taikasana = "abrakadabra";

Merkkijonomuuttujan antaminen tulostuskomennolle (tai oikeastaan mille tahansa merkkijonon parametrina ottavalle metodille) parametrina onnistuu tutulla tavalla. Alla määritellään merkkijono, joka tulostetaan.

String taikasana = "abrakadabra";
System.out.println(taikasana);
Esimerkkitulostus

abrakadabra

Merkkijonojen lukeminen ja tulostaminen

Merkkijonon lukeminen onnistuu Scannerin tarjoamalla nextLine-metodilla. Alla oleva ohjelma lukee käyttäjän nimen ja tulostaa sen seuraavalla rivillä:

Scanner lukija = new Scanner(System.in);

System.out.print("Mikä on nimesi? ");
// Luetaan käyttäjältä rivi tekstiä ja asetetaan se muuttujaan nimi
String nimi = lukija.nextLine();

System.out.println(nimi);
Esimerkkitulostus

Mikä on nimesi? Venla Venla

Merkkijonoja voi myös yhdistellä. Jos plus-operaatiota + sovelletaan kahden merkkijonon välille, syntyy uusi merkkijono, jossa kaksi merkkijonoa on yhdistetty. Huomaa nokkela välilyönnin käyttö lauseen "muuttujien" osana!

String tervehdys = "Hei ";
String nimi = "Lilja";
String hyvastely = " ja näkemiin!";

String lause = tervehdys + nimi + hyvastely;

System.out.println(lause);
Esimerkkitulostus

Hei Lilja ja näkemiin!

Loading

Merkkijonojen vertailu ja equals

Merkkijonoja ei voi vertailla yhtäsuuri kuin operaatiolla ==. Merkkijonojen vertailuun käytetään erillistä equals-komentoa, joka liittyy aina verrattavaan merkkijonoon.

String teksti = "kurssi";

if (teksti.equals("marsipaani")) {
    System.out.println("Teksti-muuttujassa on teksti marsipaani.");
} else {
    System.out.println("Teksti-muuttujassa ei ole tekstiä marsipaani.");
}

Komento equals liitetään aina siihen verrattavaan tekstimuuttujaan, "tekstimuuttuja piste equals teksti". Tekstimuuttujaa voidaan myös verrata toiseen tekstimuuttujaan.

String teksti = "kurssi";
String toinenTeksti = "pursi";

if (teksti.equals(toinenTeksti)) {
    System.out.println("Samat tekstit!");
} else {
    System.out.println("Eri tekstit!");
}

Merkkijonoja vertailtaessa on syytä varmistaa että verrattavalla tekstimuuttujalla on arvo. Jos muuttujalla ei ole arvoa, ohjelma tuottaa virheen NullPointerException, joka tarkoittaa ettei muuttujan arvoa ole asetettu tai se on tyhjä (null).

Kuten aiemmin, negaation avulla arvon voi kääntää päinvastaiseksi.

System.out.println("Eihän merkkijono ole 'maito'");
String merkkijono = "piimä";

if (!(merkkijono.equals("maito"))) {  // tosi jos ehto merkkijono.equals("maito") on epätosi
    System.out.println("ei ollut!");
} else {
    System.out.println("oli");
}
Esimerkkitulostus

ei ollut!

Loading
Loading

Merkkijonon jakaminen osiin

Merkkijonon jakaminen useampaan osaan tapahtuu merkkijonoihin liittyvällä metodilla split, jolle annetaan parametrina merkkijono, jonka kohdalta käsiteltävä merkkijono jaetaan osiin. Metodi split palauttaa merkkijonoista koostuvan taulukon. Allaolevassa esimerkissä merkkijono jaetaan osiin välilyönnin kohdalta.

String merkkijono = "eka toka kolmas neljäs";
String[] palat = merkkijono.split(" ");
System.out.println(palat[0]);
System.out.println(palat[1]);
System.out.println(palat[2]);
System.out.println(palat[3]);

System.out.println();

for (int i = 0; i < palat.length; i++) {
    System.out.println(palat[i]);
}
Esimerkkitulostus

eka toka kolmas neljäs

eka toka kolmas neljäs

Loading
Loading

Määrämuotoinen tieto

Merkkijonojen pilkkomista käytetään erityisesti silloin, kun käsitellään määrämuotoista tietoa. Määrämuotoisella tiedolla tarkoitetaan tietoa, joka noudattaa jotain tiettyä säännönmukaista muotoa. Tällainen muoto on esimerkiksi comma separated format (csv), missä arvot on eritelty toisistaan pilkuilla. Alla on esimerkki csv-muotoisesta nimiä ja ikiä sisältävästä tiedosta. Ensimmäinen sarake sisältää nimen ja toinen iän. Sarakkeet on eroteltu toisistaan pilkuilla.

Esimerkkidata

anton,2 leevi,2 lilja,1

Oletetaan, että käyttäjä syöttää yllä olevat tiedot ohjelmaan riveittäin. Syötteen lopettaminen lopetetaan tyhjällä merkkijonolla.

Ohjelma, joka tulostaa nimet ja iät toteutetaan seuraavasti.

Scanner lukija = new Scanner(System.in);
int ikienSumma = 0;
int ikienLukumaara = 0;

while (true) {
    String luettu = lukija.nextLine();
    if (luettu.equals("")) {
        break;
    }

    String[] palat = luettu.split(",");
    System.out.println("Nimi: " + palat[0] + ", ikä: " + palat[1]);
}
Esimerkkitulostus

leevi,2 Nimi: leevi, ikä: 2 lilja,1 Nimi: lilja, ikä: 1

Loading
Loading

Monimuotoisen tekstin tarkastelu

Edellä olevissa esimerkeissä tulostimme merkkijonoja. Osa määrämuotoisesta merkkijonosta voi olla numeromuotoista. Aiemmin käyttämässämme nimiä ja ikiä sisältävässä aineistossa ikä on kokonaisluku.

Esimerkkidata

anton,2 leevi,2 lilja,1

Merkkijonon pilkkominen osiin tuottaa merkkijonoista koostuvan taulukon. Mikäli teksti on määrämuotoista, voimme olettaa, että tietyssä indeksissä oleva tieto on aina tietyn muotoista — esimerkiksi yllä indeksissä yksi oleva ikä on luku.

Alla olevassa esimerkissä ohjelma laskee yllä kuvattua syötemuotoa noudattavan tiedon ikien summan. Jotta summa voidaan laskea, ikä muunnetaan luvuksi (tuttu komento Integer.valueOf())

Scanner lukija = new Scanner(System.in);
int summa = 0;

while (true) {
    String luettu = lukija.nextLine();
    if (luettu.equals("")) {
        break;
    }

    String[] palat = luettu.split(",");
    summa = summa + Integer.valueOf(palat[1]);
}

System.out.println("Ikien summa on " + summa);
Esimerkkitulostus

leevi,2 lilja,1

Ikien summa on 3

Vastaavalla tavalla voisi toteuttaa ohjelman, joka laskee henkilöiden keski-iän.

Scanner lukija = new Scanner(System.in);
int summa = 0;
int lukumaara = 0;

while (true) {
    String luettu = lukija.nextLine();
    if (luettu.equals("")) {
        break;
    }

    String[] palat = luettu.split(",");
    summa = summa + Integer.valueOf(palat[1]);
    lukumaara = lukumaara + 1;
}

if (lukumaara > 0) {
    System.out.println("Ikien keskiarvo: " + (1.0 * summa / lukumaara));
} else {
    System.out.println("Ei syötteitä.");
}
Esimerkkitulostus

leevi,2 lilja,1 Ikien keskiarvo: 1.5

Loading
Loading
Loading
Pääsit aliluvun loppuun! Jatka tästä seuraavaan osaan:

Muistathan tarkistaa pistetilanteesi materiaalin oikeassa alareunassa olevasta pallosta!