Forrige kapittel Neste kapittel

Kapittel 7 — Arrayer (tabeller)

Array som datatype

En array (éndimensjonal tabell) består av et bestemt antall dataelementer av samme type. Elementene er indeksert fra 0 og oppover.

Syntaks for deklarasjon av array:

  typenavn[] arraynavn;

eller

  typenavn arraynavn[];

Legg merke til at vi i deklarasjonen ikke sier noe om hvor mange elementer det skal være plass til. (Det gjør vi først når vi oppretter arrayen, se nedenfor.) Typenavnet kan være en hvilken som helst datatype. Navnet på arrayen velger vi selvsagt (som alle navn) slik at det er mest mulig selvforklarende, det vil si indikerer hvilken rolle arrayen skal spille i programmet. Det er likegyldig for programmets virkemåte hvilket av disse to alternativene vi bruker for å deklarere en array. Men den første av dem er mest i samsvar med deklarasjon av variable av andre datatyper. Det er den som vil bli brukt i denne teksten og tilhørende programeksempler.

Eksempler på deklarasjon av array

  int[] frekvenser;
  double[] priser;
  String[] forfattere;

Opprette array

En array vil ikke eksistere (det vil si vi kan ikke bruke den) før den er opprettet. For å opprette en array bruker vi new-operatoren ved å skrive en instruksjon på formen

  arraynavn = new typenavn[ antallElementer ];

der arraynavn og typenavn må stemme overens med det vi har skrevet i deklarasjonen og antallElementer angir hvor mange elementer (av den angitte type) arrayen skal ha plass til.

Merknad

For å opprette arrayer, bruker vi altså new-operatoren, slik vi også har gjort for å opprette objekter definert av klasser. Grunnen til dette er at i java så er også arrayer en type objekter. Arraynavnet (arrayvariabelen) vil derfor være en referanse (peker) til array-objektet, vi kan tenke på den som arrayens memory-adresse.

Eksempler

Med de arraydeklarasjonene som står ovenfor kan vi opprette følgende arrayer:

  frekvenser = new int[ 20 ];
  priser = new double[ 100 ];
  int antForfattere = 1000;
  forfattere = new String[ antForfattere ];

Antall elementer må være et heltall eller et heltallsuttrykk, for eksempel en heltallsvariabel som på forhånd har fått verdi, som i siste eksemplet ovenfor. I mange tilfelle vil det være aktuelt å foreta innlesing av antall elementer. NB! Indekseringen for en array går alltid fra 0 til antall elementer minus 1. For eksempel vil den for arrayen frekvenser gå fra 0 til 19. Arrayer blir automatisk initialisert samtidig som de blir opprettet. Numeriske arrayer (altså arrayer av numerisk datatype) blir initialisert til tallverdien 0 (eller 0.0, avhengig av datatype) på alle plasser. Arrayer av datatype boolean initialiseres automatisk til verdien false på alle plasser, mens alle arrayer av objekter, det vil si av datatype definert av en klasse eller av en array, blir initialisert til verdien null på alle plasser. For å referere til enkeltelementer i en array bruker vi arraynavn og indeks. Arraynavnet kalles derfor også for en indeksert variabel.

Eksempler

Med arrayene som er opprettet ovenfor, kan vi for eksempel skrive instruksjonene

  frekvenser[ 0 ] = 17;
  frekvenser[ 1 ] = 3;
  priser[ 5 ] = 213.50;
  forfattere[ 17 ] = "Lars Saabye Christensen";

Arrayer kjenner sin egen lengde. Vi får tak i den ved å skrive arraynavn.length. Dette er til nytte blant annet når arrayer skal gjennomløpes for prosessering av elementene. Det er da vanlig å bruke en for-løkke, der styrevariabelen samtidig tjener som arrayindeks.

Eksempler på gjennomløping, skrevet i pseudokode

  for ( int i = 0; i < frekvenser.length; i++ )
  {
    < gjør et eller annet med frekvenser[ i ] >
  }

  for ( int i = 0; i < forfattere.length; i++ )
  {
    < gjør et eller annet med forfattere[ i ] >
  }

Deklarere og opprette array samtidig

Det er tillatt å opprette en array samtidig som den blir deklarert. For eksempel kunne vi for arrayen frekvenser, som er deklarert og opprettet ovenfor, isteden ha skrevet

  int[] frekvenser = new int[ 20 ];

Opprette og initialisere array ved hjelp av initialiseringsliste

Det er mulig, samtidig som en deklarerer en array, å initialisere den ved hjelp av en liste av verdier omsluttet av krøllparenteser. For utlånsobjekter på et mediatek kunne vi for eksempel ha opprettet en array på denne måten:

  String[] utlånsobjekter = { "bok", "CD", "DVD", "spill" };

Merk deg at når det gjøres på denne måten, er det ikke tillatt å splitte opp i to instruksjoner. Vi kunne altså ikke ha skrevet

  String[] utlånsobjekter;
  utlånsobjekter = { "bok", "CD", "DVD", "spill" };

Merk deg også at vi ikke spesifiserer noen størrelse på arrayen når den blir opprettet ved hjelp av en initialiseringsliste som vist ovenfor. Riktig størrelse vil bli bestemt automatisk. Som ellers kan vi få tak i den ved (i dette tilfelle) å skrive utlånsobjekter.length. Indekseringen for en slik array vil, som for alle andre, gå fra 0 og oppover.

Programeksempel 1: Trekning av en tilfeldig måned

Vi skal lage et program som gir brukeren mulighet til gjentatte ganger å trekke en tilfeldig av årets tolv måneder. Brukeren skal hver gang få spørsmål om han/hun ønsker å trekke en ny måned. I tilfelle det svares "Ja", skal ny måned trekkes og trukket måned skal skrives ut i en meldingsboks. Svares det "Nei", skal programmet avsluttes. Fullstendig programkode for programmet er gjengitt lengre nede. Først skal vi se på noen problemer som må løses under programmeringen.

Det første problemet som vi skal ta for oss, er hvordan vi kan foreta trekning blant månedene. Siden dette med å trekke en måned er noe som det også kan bli behov for i andre sammenhenger, velger vi å definere en egen klasse som inneholder en metode for nettopp dette. Hver gang vi har behov for å trekke en tilfeldig måned, kan vi dermed opprette et objekt av denne klassen og bruke nevnte metode. Klassen har vi nedenfor kalt Trekningsautomat.

Siden det er 12 måneder, kan vi trekke måned ved å trekke et av tallene 1 til 12 og skrive ut det månedsnavnet som dette tallet svarer til. Men hvordan kan vi programmere denne tilordningen mellom tall og månedsnavn? Det kan vi få til ved å legge månedsnavnene inn i en array, for der vil hvert navn svare til en arrayindeks. Nå må vi imidlertid huske på at arrayindeksene alltid går fra 0 og oppover. Istedenfor å trekke et tall fra 1 til 12 kan vi derfor trekke et tall fra 0 til 11 og velge den måneden som har det trukne tallet som indeks i arrayen

  String[] månedsnavn = { "Januar", "Februar", "Mars", "April", "Mai",
                          "Juni", "Juli", "August", "September",
                          "Oktober", "November", "Desember" };

I klassen Trekningsautomat, som er gjengitt nedenfor, er arrayen med månedsnavn lagt inn på klassenivå. Der er det også lagt inn en slumptallsgenerator. Metoden som trekker og returnerer månedsnavn kan vi dermed skrive på følgende måte:

  public String trekkMåned()
  {
    int indeks = generator.nextInt( månedsnavn.length );
    return månedsnavn[ indeks ];
  }

Et objekt av type Trekningsautomat skal vi nå bruke i et program som virker på den måte som ble beskrevet ovenfor. Vi skal først se nærmere på hvordan vi kan få programmet til å vise dialogbokser med Ja- og Nei-knapper.

Ja-nei-dialogbokser ble introdusert i kapittel 3, og vi har brukt dem i flere programeksempler. Men på knappene i dialogboksene har det stått "Yes" og "No" istedenfor "Ja" og "Nei". Nå, som vi har lært om arrayer, har vi grunnlag for å lære hvordan vi kan få "Ja" og "Nei" på knappene, istedenfor "Yes" og "No". En slik dialogboks kan vi få ved å skrive følgende kode:

  String[] alternativer = { "Ja", "Nei" };
  JOptionPane.showOptionDialog( null,
          "Vil du trekke en måned?", "Månedstrekning",
          JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE,
          null, alternativer, alternativer[ 0 ] )

Arrayen alternativer inneholder tekstene som vi ønsker å ha på knappene i dialogboksen vår. Parametrene i kallet på metoden showOptionDialog har følgende betydning:

null
Første parameter skal normalt være referanse til foreldervindu. Et slikt har vi ikke i vårt tilfelle. Derfor brukes verdien null.
"Vil du trekke en måned?"
Tekst vi ønsker å ha inni boksen sammen med knappene.
"Månedstrekning"
Tekst til boksens tittellinje
JOptionPane.YES_NO_OPTION
Konstant som indikerer hvilke alternativer vi ønsker det skal være knapper for.
JOptionPane.QUESTION_MESSAGE
Indikerer type tekst i boksen, brukes til å velge ikon blant standardikonene.
null
Parameteren kan være referanse til egendefinert ikon. Vi bruker isteden standardikon.
alternativer
Array som inneholder knappetekstene.
alternativer[ 0 ]
Hvilket alternativ vi ønsker skal være forhåndsvalgt, det vil si hvilket som velges dersom brukeren trykker på retur-tasten, istedenfor å klikke med musa på en av knappene i boksen.

På et av bildene nedenfor kan du se boksen som denne koden resulterer i. På bildet kan du også tydelig se at "Ja"-knappen er forhåndsvalgt, ved at "Ja" på vedkommende knapp er rammet inn av en ekstra firkant. En slik finnes ikke rundt "Nei" på den andre knappen. For øvrig må denne boksen brukes på samme måte som vi tidligere har brukt bokser med "Yes" og "No" på knappene. Vi må blant annet fange opp svaralternativet som brukeren har valgt og finne ut hva det er, for å kunne velge riktig alternativ for programmets videre kjøring. Fullstendig kode for dette finnes i klassen Maanedstrekning som er gjengitt nedenfor.

 1 import java.util.Random;
 2
 3 public class Trekningsautomat
 4 {
 5   private String[] månedsnavn = { "Januar", "Februar", "Mars", "April",
 6                           "Mai", "Juni", "Juli", "August", "September",
 7                           "Oktober", "November", "Desember" };
 8   private Random generator = new Random();
 9
10   public String trekkMåned()
11   {
12     int indeks = generator.nextInt( månedsnavn.length );
13     return månedsnavn[ indeks ];
14   }
15 }
 1 import javax.swing.JOptionPane;
 2
 3 public class Maanedstrekning
 4 {
 5   public static void main( String[] args )
 6   {
 7     Trekningsautomat trekker = new Trekningsautomat();
 8     boolean flere = true;
 9     String[] alternativer = { "Ja", "Nei" };
10
11     do
12     {
13       int svar = JOptionPane.showOptionDialog( null,
14           "Vil du trekke en måned?", "Månedstrekning",
15           JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE,
16           null, alternativer, alternativer[ 0 ] );
17       flere = (svar == JOptionPane.YES_OPTION );
18       if ( flere )
19       {
20         String måned = trekker.trekkMåned();
21         JOptionPane.showMessageDialog( null, "Trukket måned: " + måned,
22             "Månedstrekning", JOptionPane.PLAIN_MESSAGE );
23       }
24     } while ( flere );
25   }
26 }

Følgende bilder viser Ja-nei-dialogboksen som vises av programmet og en dialogboks med en trukket måned, som følge av at brukeren har svart "Ja" på spørsmålet om det ønskes trekning av måned. Legg merke til at dersom brukeren klikker på Nei-knappen, så vil variabelen flere få verdi false. Det vil da ikke bli foretatt noe trekning av måned og programmet vil bli avsluttet. Du kan få lastet ned programfilene ved å klikke på følgende linker: Trekningsautomat.java, Maanedstrekning.java.

Oppgave 1

Lag et program som leser inn 10 heltall fra brukeren og skriver dem ut igjen i motsatt rekkefølge med ett tall per linje i en dialogboks. (Lagre de innleste tallene i en array.)

Oppgave 2

Som i Oppgave 1 skal du lage et program som foretar 10 innlesinger av heltall fra brukeren. Det er imidlertid bare tall som er i intervallet 1 til 50 (begge grenser inkludert) som skal lagres. Men også innlesing av tall utenfor dette intervall teller med blant de 10 innlesingene. Når innlesingene er fullført, skal programmet skrive ut (i en dialogboks) 10 linjer med stjerner. Antall stjerner på hver linje skal være lik de tallene som ble lest inn fra brukeren. På linjer som svarer til innlesinger der det ble lest inn tall utenfor intervallet 1 til 50, skal det ikke skrives noen stjerner (altså bare en blank linje).

Programeksempel 2: Fordeling av trukne slumptall

Klassen Frekvenser som er gjengitt nedenfor finnes i fila Frekvenser.java. Klassen definerer et objekt som skal kunne trekke et antall slumptall og registrere frekvensfordelingen for dem. De trukne tallene kan være fra 1 og opptil en gitt maksimalverdi. Konstruktøren mottar via parametre antall tall som skal trekkes og maksimalverdi for dem. Den lagrer de to parameterverdiene i datafeltene antall og maks.

Arrayen frekvenser skal brukes til å registrere frekvensene for slumptallene som trekkes. Denne blir opprettet av konstruktøren med antall plasser lik antall mulige utfall for slumptallene som skal trekkes. Arrayen vil ved opprettelsen automatisk bli initialisert til 0 på alle plasser. Arrayindeksene vil gå fra 0 til maks - 1. Arrayen skal brukes på den måten at frekvenser[0] skal fortelle hvor mange ganger tallet 1 ble trukket, frekvenser[1] skal fortelle hvor mange ganger tallet 2 ble trukket, og så videre. Det betyr generelt at dersom tallet n blir trukket, så er det verdien som ligger i frekvenser[n - 1] som skal økes med 1 for å registrere at nå er n blitt trukket en gang til. Det oppnår vi ved å skrive frekvenser[n - 1]++.

Trekning av slumptall og registrering av frekvenser for dem utføres av metoden trekk. (Metoden må selvsagt kalles opp for at det skal bli utført!) Slumptallsgeneratoren generator, som ble opprettet av konstruktøren, brukes til å foreta trekningen.

Metoden skrivUt har som oppgave å skrive ut resultatet av frekvensfordelingen. Når innholdet av arrayen skal skrives ut, blir den på vanlig måte gjennomløpt ved bruk av en for-løkke. De enkelte verdiene blir skrevet ut ved et kall på utskriftsområdets append-metode. Vi får lagt inn passe avstand mellom hvert (tall: frekvens)-par ved å tilføye et tabulatortegn "\t". Vi ønsker dessuten å fordele verdiene slik at det blir inntil 10 (tall: frekvens)-par på hver linje. Dersom styrevariabelen i for for-løkka er delelig med 10, betyr det at vi allerede har skrevet ut 10 (tall: frekvens)-par på vedkommende linje. Vi går da til ny linje ved å tilføye et linjeskifttegn.

Et "driverprogram" for klassen Frekvenser finnes i fila Frekvenstest.java. Denne inneholder en main-metode som oppretter et Frekvenser-objekt og gjør kall på objektets metoder trekk og skrivUt. Ved opprettelsen av objektet er det brukt konstruktørparametrene 2000 og 20. Utskriften fra programmet ble da som vist på bildet nedenfor. Siden det er slumptall som trekkes, vil frekvensfordelingen variere fra kjøring til kjøring av programmet. Men siden det er 20 forskjellige tall det trekkes blant og trekning foretas 2000 ganger, burde vi hver gang kunne vente oss at hvert tall trekkes omkring 100 ganger. På utskriften kan vi se hvor vidt dette stemmer.

 1 import javax.swing.JOptionPane;
 2 import javax.swing.JTextArea;
 3 import java.util.Random;
 4
 5 public class Frekvenser
 6 {
 7   private int antall; //antall tall som skal trekkes
 8   private int maks; //skal trekke tall i intervallet 
 9                     //fra og med 1 til og med maks
10   private int[] frekvenser; //skal inneholde frekvensene 
11                             //for tallene som trekkes
12   private Random generator;
13
14   public Frekvenser( int a, int m )
15   {
16     antall = a;
17     maks = m;
18     frekvenser = new int[ maks ];
19     generator = new Random();
20   }
21
22   //trekker slumptall og registrerer frekvenser
23   public void trekk()
24   {
25     for ( int i = 0; i < antall; i++ )
26     {
27       int trukket = 1 + generator.nextInt( maks );
28       frekvenser[ trukket - 1 ]++;  //husk at indeksering starter på 0
29     }
30   }
31
32   //Lager utskrift i et tekstområde:
33   public void skrivUt()
34   {
35     JTextArea utskrift = new JTextArea();
36     utskrift.setText( "Frekvenser for trekning av " + antall +
37                      " slumptall fra intervallet 1 til " + maks + "\n" );
38     //går gjennom frekvenstabell og skriver ut verdiene
39     for ( int i = 0; i < frekvenser.length; i++ )
40     {
41       if ( i % 10 == 0 ) //går til begynnelsen av neste linje
42       {
43         utskrift.append( "\n" );
44       }
45       utskrift.append( (i + 1) + ": " + frekvenser[ i ] + "\t" );
46     }
47
48     JOptionPane.showMessageDialog( null, utskrift, "Frekvenser",
49         JOptionPane.PLAIN_MESSAGE );
50   }
51 }

Oppgave 3

I kapittel 6, eksempel 2 er det et program der det blir simulert kast med en terning 6000 ganger. Programmet registrerer og skriver ut hvor mange ganger det blir seks på terningen. Du får nå som oppgave å omarbeide programmet slik at det registrerer og skriver ut frekvensene for alle de seks mulige terningverdiene. Bruk en array til registrering av frekvensene.

Oppgave 4

Lag et program som leser inn hele tall og lagrer dem i en array. Programmet skal imidlertid bare lagre de tall som ikke er lest inn allerede. (Arrayen skal altså ikke inneholde noen duplikater av tall.) Alle tall som leses inn skal være i intervallet 20 til 100, begge grenser inkludert. Programmet skal lese inn i alt 20 forskjellige tall fra dette intervallet. Programmet skal skrive ut feilmelding hver gang brukeren prøver seg med en verdi utenfor det nevnte intervall, og programmet skal foreta ny innlesing av dette tallet gjentatte ganger inntil det leses inn et tall fra det riktige intervallet. Når alle tallene er lest inn, skal programmet skrive ut i et tekstområde de forskjellige tallene som er lest inn. Legg inn mellomrom mellom tallene og skriv ut høgst 5 tall per linje. (I programeksempel 2 ovenfor, der det skrives ut 10 tall per linje, kan du se hvordan du kan få til utskriften på denne måten.) Programmet kan lages ved at du skriver en klasse etter følgende skisse (nødvendige import-instruksjoner må tas med i tillegg):

public class Tallduplikater
{
  <Deklarasjon av array for lagring av innleste
     tall og andre nødvendige variable og konstanter.>

  public Tallduplikater()
  {
    < Foretar nødvendig initialisering av variable >
  }

  public void lesInnTall()
  {
    < Leser inn 20 tall fra riktig intervall. Foretar eventuell ny innlesing
         for tall som ikke er i riktig intervall. For hvert innlest tall
         (fra riktig intervall) sjekkes det om samme tall er lest inn
         tidligere. Dersom det ikke er tilfelle, lagres tallet i arrayen
         for dette. >
  }

  public boolean finnes( int tall )
  {
    < Returnerer true eller false avhengig av om tall finnes i arrayen
                             med innleste tall. >
  }

  public void visInnlesteTall()
  {
    < Skriver innhold av arrayen med innleste tall ut i tekstområde,
         høgst 5 tall per linje. Viser tekstområdet i en meldingsboks.>
  }


}

I tillegg må du lage et "driverprogram" som oppretter et objekt av den definerte typen og foretar de nødvendige metodekallene.

Datatypen char

Den primitive datatypen char brukes til å representere enkelttegn. Verdiene vil være de unicode-verdiene som identifiserer tegnene. En tegn-literal omsluttes av apostrofer. Vi kan for eksempel skrive

  char tegn = 'a';

Merk deg forskjellen mellom 'a' og "a"! Den første er et tegn (mer presist: en verdi av datatypen char), mens den andre er en tekststreng (det vil si en verdi av datatypen String). Vi kan, selvsagt, også opprette arrayer av tegn, slik som

  char[] vokaler = { 'a', 'e', 'i', 'o', 'u', 'y', 'æ', 'ø', 'å' };

Men merk deg at en array av tegn ikke er det samme som en String! (På den andre side kan vi på grunnlag av en array av tegn opprette en String med tilsvarende innhold. Dette er noe vi kommer tilbake til når vi skal se nærmere på String-datatypen.)

Litt om String-objekter

Tekststrenger (det vil si String-objekter) er på samme måte som arrayer indeksert fra 0 og oppover. String-objekter har også det til felles med arrayer at de kjenner sin egen lengde. Lengden returneres av String-metoden length().

Eksempel

  String eks = "eksempel";
  int stringlengde = eks.length();  // stringlengde == 8
  char[] stringtegn = { 'e', 'k', 's', 'e', 'm', 'p', 'e', 'l' };
  int tabellengde = stringtegn.length;  // Merk forskjellen!
                                     // tabellengde == 8

For å få tak i tegnet som ligger i en gitt indeksposisjon i en streng, bruker vi String-metoden charAt.

Eksempel

  String eks = "eksempel";
  char tegn = eks.charAt( 2 );  // tegn == 's'

Programeksempel 3: Registrering og opptelling av vokaler

Programmet Vokaler.java leser inn en tekststreng fra brukeren. Programmet skriver ut alle vokaler som forekommer i den innleste tekststrengen og det totale antallet vokaler. Skjermbildene viser eksempel på en kjøring av programmet.

Kildekoden er gjengitt nedenfor.

 1 import javax.swing.JOptionPane;
 2
 3 public class Vokaler
 4 {
 5   public static void main( String[] args )
 6   {
 7     String input = JOptionPane.showInputDialog(
 8             "Programmet teller og skriver " +
 9             "ut vokalene i tekststrengen du skriver." );
10
11     char[] vokaler = { 'a', 'e', 'i', 'o', 'u', 'y', 'æ', 'ø', 'å' };
12     int antall = 0;
13     String output = "Vokaler i innlest tekst:\n";
14
15     for ( int i = 0; i < input.length(); i++ )
16     {
17       char tegn = input.charAt( i );
18
19       for ( int j = 0; j < vokaler.length; j++ )
20       {
21         if ( tegn == vokaler[ j ] )
22         {
23           antall++;
24           output += tegn + "  ";
25           //vil bare ha 5 vokaler på hver linje i utskriften
26           if ( antall % 5 == 0 )
27             output += "\n";
28         }
29       }
30     }
31
32     output += "\nI alt " + antall + " vokaler.";
33     JOptionPane.showMessageDialog( null, output, "Vokaler",
34             JOptionPane.PLAIN_MESSAGE );
35   }
36 }

Oppgave 5

Lag et program som leser inn en tekststreng fra brukeren. Programmet skal telle opp og skrive ut antall forekomster det i den innleste tekststrengen er av de forskjellige bokstavene i alfabetet, altså antall a-er, antall b-er, etc. Det skal skilles mellom små og store bokstaver. (Programmet skal altså telle opp både antall a-er og A-er, og tilsvarende for de andre bokstavene.)

Operasjoner på hele arrayer

Det er viktig å ha klart for seg at arrayer er objekter og at en array-variabel bare er en peker (referanse) til array-objektet. Dette har betydning når vi foretar tilordning mellom array-variable og når array-variable er metodeparametre. Vi kan belyse dette gjennom et lite eksempel.

Eksempel

  int[] x = { 1, 2, 3 };
  int[] y = { 4, 5, 6 };

Nå peker x og y på hvert sitt array-objekt. Vi foretar så følgende instruksjon:

  y = x;

Resultatet blir at y nå vil peke på samme array-objekt som x peker på, x og y vil ikke lenger peke på hvert sitt array-objekt. Array-objektet som y pekte på tidligere vil vi miste fordi vi ikke lenger har noen peker til det. (Det vil automatisk bli slettet av java-systemet.)

Dersom vi ikke er klar over at array-variable fungerer som pekere til objekter, kan vi feilaktig tro at instruksjonen y = x; ovenfor har som resultat at innholdet i arrayen som x representerer vil bli kopiert over til arrayen som y representerer. Dersom det er dette vi ønsker, og altså dessuten at x og y fortsatt skal representere hver sin array, kan vi skrive følgende kode:

  if ( x.length <= y.length )
  {
    for ( int i = 0; i < x.length; i++ )
      y[ i ] = x[ i ];
  }

Krøllparentesene er her strengt tatt unødvendige, men de bidrar til å klargjøre strukturen. Det finnes for øvrig i javas klassebibliotek (i pakken java.lang) det vi kan kalle en verktøymetode med navn arraycopy som kan brukes til å kopiere innholdet i en array (eller en del av denne) over i en annen. I vårt tilfelle (med x og y slik de opprinnelig ble opprettet ovenfor) kunne vi ved bruk av denne verktøymetoden ha skrevet

  System.arraycopy( x, 0, y, 0, x.length );

Parametrene i metoden arraycopy har følgende betydning:
1. parameter er arrayen som det skal kopieres fra, kilden;
2. parameter er indeksen for startposisjonen (for kopieringen) i kilden;
3. parameter er arrayen det skal kopieres til, målet;
4. parameter er indeksen for startposisjonen (for kopieringen) i målet;
5. parameter er antall elementer som skal kopieres.

Arrayer som metodeparametre

Det er en svært viktig forskjell i virkemåte mellom parametre av primitiv datatype og parametre av arraytype eller klassetype (det vil si pekere). Definisjon av en metode med én parameter ser generelt slik ut (uttrykt i pseudokode):

  returdatatype metodenavn( datatype parameter )
  {
    < instruksjoner som skal utføres av metoden,
         bruker parameter som en lokal variabel >
  }

Ved kall på metoden må det brukes en aktuell parameter (også kalt argument) av riktig datatype og med tildelt verdi:

  datatype variabel = ...;
  //metodekall:
  returdatatype r = metodenavn( variabel );

Virkemåten for metodens aktuelle parameter variabel kan vi beskrive slik:

Programeksempel 4: Array som metodeparameter

Programmet som består av de to klassene Arrayparametre og Arraybehandler viser et eksempel på hvordan en arraytype virker både som parameter og som retur-datatype for metoder. Programmet er organisert ved at klassen Arraybehandler inneholder noen metoder som utfører diverse operasjoner på arrayer, mens klassen Arrayparametre er et testprogram for de definerte metodene.

Klassen Arraybehandler inneholder metoder for å opprette og returnere en slumptallsarray av ønsket størrelse, reversere mottatt array, tilføye utskrift av mottatt array i tekstområdet metoden mottar, samt en metode som dobler og returnerer mottatt heltallsparameter. Klassen er gjengitt nedenfor. Vi skal se litt nærmere på de enkelte metodene i klassen.

Metoden lagListe oppretter og returnerer en array fylt av slumptall. Legg merke til at arrayen opprettes inne i metoden. Metoden returnerer array-variabelen. Denne vet vi er en referanse til arrayobjektet. Det vil derfor være den som blir returnert av metoden.

Metoden reverser har en array som parameter. Metoden reverserer rekkefølgen til arrayelementene. Metoden mottar altså (via parameteren) en referanse til arrayobjektet og endrer dette objektet. Den returnerer ikke noe.

Metoden print har som oppgave å tilføye på et tekstområde en utskrift av innholdet i en array. Metoden mottar via parametre både arrayen den skal skrive ut og det tekstområdet den skal skrive det ut på. Dessuten mottar den en overskrift som skal stå over arrayinnholdet. Dermed kan metoden skrive ut innhold av forskjellige arrayer og med forskjellig overskrift for hver gang den blir kalt opp, og om ønskelig, på forskjellige tekstområder. Legg merke til at den jobber med de objektene den mottar, den returnerer ikke noe.

Metoden dubler har en int-parameter som den dobler og returnerer. Siste arrayelement brukes som aktuell parameter når det gjøres kall på metoden i klassen Arrayparametre. Utskrift av dette siste arrayelementet før og etter metodekallet viser at metoden ikke endrer verdien til arrayelementet. Husk at metodeparametre fungerer som lokale variable i metoden. Aktuelle parametre gir startverdi til dem. I vårt tilfelle gir siste arrayelement startverdi til den lokale variabelen k. Det er verdien til denne lokale variabelen metoden dobler og som den returnerer den doblete verdien til. Verdien til siste arrayelement er uberørt av dette.

 1 import java.util.Random;
 2 import javax.swing.JTextArea;
 3
 4 public class Arraybehandler
 5 {
 6     //returnerer slumptallsarray med lengde lik første parameter og
 7     //slumptall fra og med 0 til andre parameter
 8     public int[] lagListe( int lengde, int grense )
 9     {
10       int[] slumptall = new int[ lengde ];
11       Random generator = new Random();
12       for ( int i = 0; i < slumptall.length; i++ )
13         slumptall[ i ] = generator.nextInt( grense );
14       return slumptall;
15     }
16
17     //reverserer arrayen som er parameter
18     public void reverser( int[] tabell )
19     {
20       int n = tabell.length - 1;
21       for ( int i = 0; i < tabell.length / 2; i++ )
22       {
23         int elem = tabell[ i ];
24         tabell[ i ] = tabell[ n - i ];
25         tabell[ n - i ] = elem;
26       }
27     }
28
29     //printer ut array med ønsket overskrift
30     public void print(JTextArea utskrift, String overskrift, int[] liste)
31     {
32       utskrift.append( overskrift + "\n" );
33       for ( int i = 0; i < liste.length; i++ )
34       {
35         utskrift.append( String.valueOf( liste[ i ] ) + "\t" );
36         if ( (i + 1) % 10 == 0 )
37           utskrift.append( "\n" );
38       }
39     }
40
41     // dobler parameterverdien og returnerer den
42     public int dubler( int k )
43     {
44       k *= 2;
45       return k;
46     }
47 }

Klassen Arrayparametre som er gjengitt nedenfor inneholder bare en main-metode som fungerer som testprogram for Arraybehandler-klassen. Det gjør den på den måten at den oppretter et Arraybehandler-objekt og bruker dette objektet til å gjøre kall på de forskjellige metodene i Arraybehandler-klassen. Den lager dessuten utskrifter som viser virkningen av de forskjellige metodene som blir kalt opp. Merk deg hvordan metodene blir kalt opp og hvordan deres returverdier blir fanget opp og brukt videre i programutførelsen. Legg merke til at print-metoden blir kalt opp to ganger, først for å skrive ut den opprinnelige arrayen, og deretter for å skrive ut den reverserte arrayen. De to utskriftene blir forsynt med hver sin overskrift. Legg for øvrig merke til at det er de forskjellige metodene som blir kalt opp fra Arraybehandler-klassen som gjør det aller meste av jobben under programutførelsen!

Instruksjonen på linje 15 skalerer størrelsen på tabulatorhoppene som escapetegnet "\t" gir. Hensikten er å få passe avstand mellom arrayverdiene i utskriften.

 1 //Illustrasjon av arrayparametres virkemåte sammenliknet med
 2 //parametre av primitiv type
 3 import javax.swing.JTextArea;
 4 import javax.swing.JOptionPane;
 5
 6 public class Arrayparametre
 7 {
 8   public static void main( String[] args )
 9   {
10     Arraybehandler behandler = new Arraybehandler();
11     int tallgrense = 20;
12     //oppretter slumptallsliste og printer den ut
13     int[] liste = behandler.lagListe( 10, tallgrense );
14     JTextArea utskrift = new JTextArea();
15     utskrift.setTabSize(5);
16     utskrift.setText( "Illustrasjon av arrayparametres virkemåte " +
17                       "sammenliknet med parametre av primitiv type\n" );
18     behandler.print( utskrift, "Opprinnelig array", liste );
19
20     //reverserer lista og printer ut reversert liste
21     behandler.reverser( liste );
22     utskrift.append(
23             "\nReverserer arrayen ved å bruke den som parameter " +
24             "i en metode som utfører reverseringen." );
25     behandler.print( utskrift, "\nReversert array", liste );
26
27     //printer ut siste listeelement
28     utskrift.append(
29             "\nSiste arrayelement " + liste[ liste.length - 1 ]  +
30             " skal brukes som aktuell parameter en metode som dobler " +
31             "mottatt parameterverdi." );
32
33     //viser virkning av dubleringsmetode
34     int doblet = behandler.dubler( liste[ liste.length - 1 ] );
35     utskrift.append( "\nDoblet verdi av aktuell parameter: " +
36               doblet );
37     utskrift.append( "\nAktuell parameter har beholdt sin verdi: " +
38           liste[ liste.length - 1 ] );
39
40     JOptionPane.showMessageDialog( null, utskrift, "Arrayparametre",
41         JOptionPane.PLAIN_MESSAGE );
42   }
43 }

Bildet nedenfor viser resultatet av en kjøring av programmet. Siden det bruker slumptall, vil det bli forskjellig resultat fra kjøring til kjøring.

Merknad: Anonyme arrayer

I java er det mulig å opprette arrayer uten å ha noen referanse til dem, slik at vi får det vi kan kalle en anonym array. Her er eksempel på det:

  new int[] { 2, 3, 5, 7, 11, 13 };

Virkningen er at det blir opprettet et array-objekt med det innholdet som er listet opp mellom krøllparentesene. Datatypen må selvsagt stemme med det som er angitt foran, i dette tilfelle int. Størrelsen på arrayen blir lik det antall elementer som er listet opp.

Det er neppe ofte vi får bruk for å gjøre dette, men det er greit å kjenne til det, slik at vi vet hva det betyr i tilfelle vi treffer på det når vi leser andres programkode. For øvrig kan det vel tenkes at det kan være aktuelt å bruke en anonym array for eksempel som aktuell parameter i enkelte metodekall. I main-metoden til klassen Arrayparametre ovenfor hadde det for eksempel vært tillatt med følgende metodekall:

    behandler.print(utskrift, "De første primtall", new int[] { 2, 3, 5, 7, 11, 13 });

Det er også mulig å bruke denne teknikken for å reinitialisere en array direkte, uten å måtte opprette en ny variabel, slik som i følgende eksempel:

  String[] arbeidsdager = {"mandag", "tirsdag", "onsdag", "torsdag", "fredag"};
  ...
  arbeidsdager = new String[] {"man", "tir", "ons", "tor", "fre"};

Koden i siste linje ovenfor er en forkortelse for følgende to kodelinjer:

  String[] anonym = new String[] {"man", "tir", "ons", "tor", "fre"};
  arbeidsdager = anonym;

Utvidet for-løkke

Vi har sett at det ofte er behov for å bruke for-løkker for gjennomløping av hele eller deler av arrayer. Fra og med javaversjon 1.5 er det innført en forenklet skrivemåte som noen ganger kan brukes for for-løkker som skal gjennomløpe hele arrayen. Som eksempel på denne tar vi for oss følgende metode som skal beregne og returnere summen av alle elementene i en array av hele tall. (Følgende versjon av metoden er skrevet på tradisjonell måte.)

  public int sum( int[] liste )
  {
    int total = 0;
    for ( int i = 0; i < liste.length; i++ )
      total += liste[ i ];
    return total;
  }

Uttrykt med den nye versjonen av for-løkke kan vi skrive samme metoden på følgende måte (men den forutsetter bruk av javaversjon 1.5 eller seinere versjon):

  public int sum( int[] liste )
  {
    int total = 0;
    for ( int element : liste )
      total += element;
    return total;
  }

Vi ser at den nye versjonen av for-løkke er litt mer kompakt, men den virker, iallfall ved første øyekast, også mer kryptisk. Vi kan lese den noe sånn som "for alle hele tall element i arrayen liste ...". Løkka vil bli utført for alle elementene i vedkommende array. For hvert løkkegjennomløp vil variabelen element bli satt lik vedkommende arrayelement. Datatypen for variabelen må derfor stemme overens med datatypen for elementene i vedkommende array. Navnet til variabelen (element i dette tilfelle) kan velges fritt, slik som for variable ellers. En slik "utvidet for-løkke" har imidlertid noen begrensninger:

På grunn av de nevnte begrensninger er det ikke så ofte vi kan bruke en løkke av denne type, og vi trenger selvsagt ikke å gjøre det i det hele tatt. Det er ingen ting i veien for å fortsette med den tradisjonelle løkketypen også i de tilfeller der det er mulig å bruke den nye.

Metoder med varierende antall argumenter

Parallelt med introduksjonen av den utvidete for-løkka, ble det i javaspråket innført en mulighet for at en metode kan ha et varierende antall argumenter av samme datatype. Syntaksen for dette er som antydet her:

  returverditype metodenavn(datatype ... parameternavn)
  {
    < metodeinnhold >
  }

Det som signaliserer at det aktuelle parameterantallet kan være varierende, er altså de tre prikkene ... mellom datatype og parameternavn. Ved kall på metoden kan vi bruke så mange paramtre vi vil av den spesifiserte typen, eventuelt ingen. Vi lister da opp parametrene med komma mellom hver parameter. I tillegg til den uspesifiserte lista av parametre kan metoden ha andre parametre, så mange vi vil. Men det er et krav at lista med varierende antall parametre må stå til slutt, og det kan bare være én slik liste.

Reint teknisk virker dette på den måten at parametrene som kan variere i antall blir lagt inn i en array når metoden blir utført. Navnet på vedkommende parameter er derfor i virkeligheten en arrayvariabel av den datatype som er spesifisert. Inni metoden kan denne arrayen gjennomløpes for prosessering. Til dette kan vi bruke en for-løkke. Siden det i dette tilfelle vil være hele arrayen som skal gjennomløpes, kan vi bruke en utvidet for-løkke. Selvsagt kunne vi også brukt en vanlig for-løkke.

Det er sannsynligvis ikke så ofte du vil ha bruk for å programmere med denne type parameterliste, men igjen så er det nyttig å kjenne til syntaksen, slik at du kan forstå betydningen i tilfelle du treffer på den i kode som andre har skrevet.

Eksempel

For å lage et eksempel på definisjon av metode med varierende antall parametre, skal vi gå tilbake til eksempel 3 i kapittel 6. Det ble der laget tre forskjellige versjoner av metoden antSekunder for konvertering til sekunder av et tidsspenn som kunne angis enten i bare timer, i timer og minutter, eller i både timer, minutter og sekunder. De tre metodene kunne vi isteden ha skrevet som én enkelt metode på følgende måte:

  public int antSekunder(int ... tid)
  {
    int total = 0; //antallet som skal returneres
    int faktor = 3600;
    for (int antall : tid)
    {
      total += antall * faktor;
      faktor /= 60;
    }
    return total;
  }

Med denne definisjonen kunne vi skrevet metodekallene akkurat på samme måte som vi ville ha gjort med den opprinnelige versjonen der vi hadde tre overloadete metoder.

Flerdimensjonale arrayer

Elementene i en array kan være av en hvilken som helst datatype. De kan derfor også være av type array, slik at vi får en array av arrayer, eller det vi heller kaller en flerdimensjonal array. Det gjøres sjelden bruk av arrayer av større dimensjon enn 2. Vi begrenser oss derfor til dette. Når vi bruker todimensjonale arrayer, kan detaljene utformes på litt forskjellige måter. Vi skal først se på noen enkle eksempler for å belyse dette.

Eksempel 1

Vi skal opprette en tabell av desimaltall med 4 rader og 5 kolonner:

  double[][] tabell = new double[ 4 ][ 5 ];

I en todimensjonal array har vi to indekser, der første indeks refererer til (horisontal)rad (linje), mens andre indeks refererer til kolonne (vertikalrad). Rader og kolonner er indeksert fra 0 og oppover. For eksempel vil tabell[0][0] referere til verdien som er på første rad og i første kolonne, mens tabell[2][3] vil referere til verdien som er på tredje rad og i fjerde kolonne.

Numeriske arrayer initialiseres automatisk til tallverdi null, mens arrayer av datatype definert av en klasse blir initialisert automatisk til pekerverdien null. Som for endimensjonale arrayer, er det imidlertid også for todimensjonale arrayer mulig å initialisere ved bruk av initialiseringslister samtidig som arrayen deklareres, som vist i følgende eksempel:

Eksempel 2

  int[][] tabell = { { 1, 2, 3 }, { 4, 5, 6 } };

Arrayen blir opprettet radvis, slik at vi i dette tilfelle får en array som på første rad inneholder tallene 1, 2 og 3, mens den på andre rad har tallene 4, 5 og 6. Når arrayen blir opprettet på denne måten, angir vi altså ingen dimensjoner og bruker heller ikke new-operatoren.

En todimensjonal array er altså egentlig en array av arrayer. Vi vet at hver array i seg selv er et objekt og at arrayvariablene egentlig er pekere til arrayobjektene. I tilfelle array av arrayer, betyr dette at i arrayen tabell som ble opprettet i eksempel 2, så vil tabell[0] være en peker til den endimensjonale arrayen som utgjør første rad i den todimensonale arrayen vår. På tilsvarende måte vil tabell[1] være en peker til den endimensonale arrayen som utgjør andre rad. Om vi ønsker det, kan vi faktisk bruke denne kunnskapen til å bytte om radene i den todimensonale arrayen vår. Det kan vi oppnå ved å skrive følgende kode:

  int[] rad = tabell[0]; //Oppretter en ekstra peker til første rad.
  tabell[0] = tabell[1]; //Erstatter første rad med den andre.
  tabell[1] = rad; //Erstatter andre rad med den som opprinnelig var først.

I en todimensjonal array er det ikke noe krav om at de endimensjonale arrayene som utgjør radene skal være av samme lengde. Vi kan derfor ha tabeller med varierende radlengde. Følgende kode vil gi en array der første rad har lengde 3, mens andre rad har lengde 2:

Eksempel 3

  int[][] varTabell = { { 1, 2, 3 }, { 4, 5 } };

I eksempel 1 ovenfor ble begge dimensjoner spesifisert da den todimensjonale arrayen ble opprettet. (I de andre eksemplene har vi brukt initialiseringslister.) Vi behøver ikke i første omgang spesifisere mer enn den første dimensjonen, det vil si den som angir antall rader. Den andre, altså den som angir antall kolonner, kan vi vente med. Dette er aktuelt å gjøre når vi skal opprette en todimensjonal array med varierende radlengde. Kode for dette kan se ut som i følgende eksempel, uttrykt i pseudo-kode:

Eksempel 4

  int antRader = ...;
  int[][] fleksitabell = new int[ antRader ][];
  //oppretter radene:
  for ( int i = 0; i < fleksitabell.length; i++ )
    fleksitabell[ i ] = new int[ < lengde, dvs. antall kolonner for rad nummer i > ];

Gjennomløping av todimensjonal array

Når vi skal gjennomløpe en todimensjonal array, bruker vi vanligvis en dobbel for-løkke, der den ytre løkka gjennomløper radene, mens den indre løkka gjennomløper hver enkelt rad. For arrayen i eksempel 4 kan en slik gjennomløping se ut på følgende måte, uttrykt i pseudo-kode:

Eksempel 5

  for ( int rad = 0; rad < fleksitabell.length; rad++ )
  {
    for ( int kolonne = 0; kolonne < fleksitabell[ rad ].length; kolonne++ )
    {
      < gjør et eller annet med fleksitabell[ rad ][ kolonne ] >
    }
  }

Programeksempel 5: Todimensjonal tabell med varierende radlengde

Vi skal lage et program som simulerer utlånstall i et bibliotek for alle årets dager. Utlånstallene skal genereres som slumptall og lagres i en todimensjonal array. (For enkelhets skyld bryr vi oss ikke om at på enkelte dager vil utlånstallet i virkeligheten være null, fordi biblioteket er stengt.) Arrayen har en rad for hver måned i året, altså 12 rader. Hver rad skal ha like mange plasser som det er dager i vedkommende måned. (Vi ser bort fra skuddår.) Dette kan vi få til ved å gå fram som det er vist i klassen Bokutlaan nedenfor, der arrayen utlån blir opprettet i klassens konstruktør. Klassen inneholder metoden genererData som gjennomløper arrayen og legger inn et slumptall på hver plass. Metoden skrivUt gjennomløper også arrayen. Den tilføyer arrayverdiene i det tekstområde som den mottar som parameter. Fila som inneholder klassen kan du laste ned ved å klikke på følgende link: Bokutlaan.java.

 1 import javax.swing.JTextArea;
 2 import java.util.Random;
 3
 4 public class Bokutlaan
 5 {
 6   private int[] månedsdager = { 31, 28, 31, 30, 31, 30, 31, 31, 30,
 7     31, 30, 31 };
 8   private String[] månedsnavn = { "januar", "februar", "mars", "april",
 9     "mai", "juni", "juli", "august", "september", "oktober",
10     "november", "desember" };
11   private int[][] utlån; // skal inneholde simulerte utlånsdata
12
13   public Bokutlaan()
14   {
15     //oppretter 12 endimensjonale arrayer for månedene
16     utlån = new int[ månedsdager.length ][];
17     //oppretter en array med riktig lengde for hver måned 
18     for ( int i = 0; i < utlån.length; i++ )
19       utlån[ i ] = new int[ månedsdager[ i ] ];
20   }
21
22   //genererer utlånstall som slumptall
23   public void genererData()
24   {
25     Random generator = new Random();
26     //gjennomløper den to-dimensjonale arrayen tabell og genererer
27     //verdier som slumptall
28     for ( int rad = 0; rad < utlån.length; rad++ )
29     {
30       for ( int kolonne = 0; kolonne < utlån[ rad ].length; kolonne++ )
31         utlån[ rad ][ kolonne ] = generator.nextInt( 500 );
32     }
33   }
34
35   //lager tabellutskrift i tekstområde
36   public void skrivUt( JTextArea utskrift )
37   {
38     //overskrift
39     utskrift.append( "Utlånstall\n\t" );
40     for ( int dag = 1; dag <= månedsdager[0]; dag++ )
41       utskrift.append( dag + ".\t" );
42     utskrift.append( "\n" );
43     //tabellutskrift
44     for ( int rad = 0; rad < utlån.length; rad++ )
45     {
46       utskrift.append( månedsnavn[ rad ] + "\t" );
47       for ( int kolonne = 0; kolonne < utlån[ rad ].length; kolonne++ )
48         utskrift.append( utlån[ rad ][ kolonne ] + "\t" );
49
50       utskrift.append( "\n" );
51     }
52   }
53 }

Programmet Tabelltest som er gjengitt nedenfor, oppretter et Bokutlaan-objekt og gjør kall på dets metoder genererData og skrivUt. Som parameter i den siste brukes et tekstområde. I tidligere eksempler har vi opprettet et slikt ved å bruke default-konstruktør. Størrelsen vil da bli bestemt automatisk av de data vi putter inn i det, det vil si av hvor mange linjer vi legger inn, og hvor lang den lengste av disse er. I dette programmet vil linjene være så lange at tekstområdet ville bli for bredt for skjermen. Vi ønsker derfor å lage det smalere, og at vi isteden skal kunne bruke et skrollefelt for å kunne se på de enkelte delene av tekstområdet.

Størrelse på et tekstområde kan vi bestemme ved å bruke to konstruktørparametre, én for ønsket antall rader, og én for ønsket antall kolonner, slik det er gjort i instruksjonen

    JTextArea utskrift = new JTextArea( 15, 60 );

Kolonnebredde, her lik 60, må vi oppfatte som antall synlige tegn på hver linje i tekstområdet. (De enkelte tegn vil vanligvis ha forskjellig bredde, vi må derfor oppfatte tallet som et gjennomsnittstall.) Det er her viktig å være klar over at konstruktørparametrene ikke begrenser antall linjer det er mulig å legge inn i tekstområdet, eller hvor lang hver slik linje kan være. Det parametrene bestemmer, er hvor mye som skal være synlig samtidig på skjermen. Det som eventuelt er usynlig, er det da ønskelig å kunne se på ved å foreta skrolling. Det oppnår vi ved at vi legger tekstområdet vårt inn i en JScrollPane slik det er gjort i følgende instruksjon:

    JScrollPane skrollefelt = new JScrollPane( utskrift );

Legg merke til at det da er skrollefeltet vi legger inn som komponent i meldingsboksen, ikke tekstområdet:

    JOptionPane.showMessageDialog( null, skrollefelt, "Utlånsdata",
        JOptionPane.PLAIN_MESSAGE );

Instruksjonen

    utskrift.setEditable( false );

har som virkning at det ikke vil være mulig for brukeren å klikke seg inn i det tekststområde som vises og endre dets verdier. Dersom vi hadde utelatt denne instruksjonen, ville det vært mulig.

 1 import javax.swing.JTextArea;
 2 import javax.swing.JOptionPane;
 3 import javax.swing.JScrollPane;
 4
 5 public class Tabelltest
 6 {
 7   public static void main( String[] args )
 8   {
 9     Bokutlaan simulator = new Bokutlaan();
10     JTextArea utskrift = new JTextArea( 15, 60 );
11     utskrift.setEditable( false );
12     utskrift.setTabSize(6);
13     JScrollPane skrollefelt = new JScrollPane( utskrift );
14
15     simulator.genererData();
16     simulator.skrivUt( utskrift );
17     JOptionPane.showMessageDialog( null, skrollefelt, "Utlånsdata",
18         JOptionPane.PLAIN_MESSAGE );
19   }
20 }

Følgende bilder viser resultatet av en kjøring av programmet. På det andre bildet er det skrollet til den del av tekstområdet som er lengst til høyre. Vi ser der tydelig at radene i arrayen har fått forskjellig lengde.

Forrige kapittel Neste kapittel

Copyright © Kjetil Grønning og Eva Hadler Vihovde, revidert 2014