javabog.dk  |  << forrige  |  indhold  |  næste >>  |  programeksempler  |  om bogen

3 Objekter

Indhold:

Kapitlet forudsættes i resten af bogen.

Forudsætter kapitel Fejl: Henvisningskilde ikke fundet Fejl: Henvisningskilde ikke fundet.

3.1 Objekter og klasser

Hidtil har vi kun brugt de simple typer (som int, boolean og double). Et javaprogram vil ofte udføre mere komplekse opgaver og dermed have brug for objekter. Et objekt repræsenterer en eller anden (ofte fysisk) ting og indeholder sammensatte data om denne ting, f.eks. et hus-objekt (med adresse, matrikelnummer, antallet af døre og vinduer ...), en bil, en person, en bankkonto, en selvangivelse, en ordre, et dokument ...

Objekter kan klassificeres i forskellige kategorier, kaldet klasser. F.eks. kunne man sige, at alle hus-objekter tilhører Hus-klassen. Hus-klassen er en beskrivelse af alle slags huse.

Næsten alt er repræsenteret som objekter i Java og der findes tusindvis af foruddefinerede klasser til ting, som man ofte har brug for som programmør såsom: tekststrenge, datoer, lister, filer, mapper, vinduer, knapper, netværksforbindelser, webadresser, billeder, lyde ...

Et objekt indeholder de data, der er nødvendige for at beskrive det, som objektet repræsenterer. Et Fil-objekt har oplysninger om den fil, det repræsenterer: Navn, placering, type, dato for oprettelse og indhold. Et Person-objekt har måske variabler for fornavn, efternavn, CPR-nummer.

Et objekt kan også indeholde navngivne programstumper, som kan udføres ved at give objektet besked om det. Disse programstumper kaldes metoder og kan opfattes som spørgsmål eller kommandoer, som man bruger til at undersøge og manipulere indholdet af objektet med.

Et Fil-objekt har måske metoden "omdøb()", der ændrer filens navn, et Person-objekt kan måske give personens alder med metoden "hvadErDinAlder()".

Et objekt kan indeholde metoder og data (variabler)
En metode kan ændre på objektets data, når den udføres

Ligesom med de simple typer afhænger det af objektets type, dets klasse, hvad man kan gøre med det. Ordet "klasse" skal forstås i betydningen "kategori, gruppe". Alle objekter kan klassificeres som værende af en bestemt type (klasse), f.eks. Streng, Dato, Fil, Knap.

Objekter af samme klasse forstår de samme beskeder (kommandoer og spørgsmål) og indeholder samme slags data. Objekter af klassen Person indeholder f.eks. begge et navn, men navnene (data) i de to person-objekter, kan være forskellige.

Et objekts type kaldes dets klasse
Klassen bestemmer, hvilke metoder og data et objekt har

Vi tegner klasser, som vist her til højre.

Øverst er klassens navn, dernæst data og nederst metoderne.

Dette er en del af UML-notationen (Unified Modelling Language), en notation, der ofte bliver anvendt i forbindelse med objektorienteret programmering.

I dette kapitel vil vi bruge objekter fra foruddefinerede klasser. Vi har valgt at kigge nærmere på Point, Rectangle, Scanner, String, Date og ArrayList. String og ArrayList er nok de mest brugte klasser overhovedet og er uundværlige i praktisk programmering. De andre klasser bruges ikke så ofte, men er velegnede til at illustrere begreberne.

3.2 Punkter (klassen Point)

Det første objekt, vi vil arbejde med, er Javas Point-objekt, der repræsenterer et punkt. I Java indeholder et punkt to heltalsvariabler, nemlig en x- og en y-koordinat. Vi vil senere bruge Point-klassen, når vi kommer til programmering af grafik.

3.2.1 Erklæring og oprettelse

For at kunne arbejde med et objekt, har man brug for en variabel, der refererer til objektet. En variabel af typen Point (der refererer til et punkt) erklæres ved at skrive

  Point p;

Ligesom med de simple typer skriver man typen (Point) efterfulgt af variabelnavnet.

Nu har vi defineret, at p er en variabel til objekter af typen Point og vi kan lave et nyt Point-objekt, som vi sætter p til at pege på1:

  p = new Point();

Vi skriver altså new og klassens navn (Point) efterfulgt af parenteser med startværdier for objektet. Her giver vi ingen startværdier og parentesen er derfor tom.

Et objekt oprettes med new
Når et objekt oprettes, sørger det for at sætte dets data til nogle fornuftige startværdier


p refererer til et punktobjekt.
Objektet har x=0 og y=0

I dette tilfælde vil punktet starte med at have koordinaterne (0,0) og situationen er, som vist på figuren til højre: p peger hen på et objekt, der har en x- og y-variabel, som begge er sat til 0.

Man kan sige, at hver gang vi anvender new-operatoren, bruger vi klassen som en slags støbeform, til at skabe et nyt objekt med.

3.2.2 Objekters felter

Vi kan undersøge objektet p's variabler (felter). Her erklærer vi en anden variabel, a, ...

    int a;

... og gemmer p's x-koordinat i variablen:

    a = p.x;

p's x-koordinat får man fat i, ved at skrive p punktum x. Vi kan derefter udskrive a:

    System.out.println("a: "+a);

Man kan også udskrive koordinaterne direkte, uden at bruge a som mellemvariabel:

    System.out.println("x-koordinat: "+p.x);
    System.out.println("y-koordinat: "+p.y);

Vi kan også ændre p's koordinater:


Efter tildeling af p.x og p.y

    p.x = 110;
    p.y = 210;

Variablerne x og y i Point-objektet kan behandles fuldstændig som andre variabler af typen int, når vi bare husker at skrive "p." foran. F.eks. kan man tælle x-koordinaten op med 5:

    p.x = p.x + 5;

x og y kaldes objektvariabler (felter), fordi de tilhører objektet p.

3.2.3 Metodekald

I stedet for at ændre objektet udefra kan vi bede objektet selv udføre ændringen. Metoden move() flytter punktet til et bestemt koordinatsæt, dvs. den


Efter kald af move(200,300)

ændrer x- og y-koordinaten.

    p.move(200,300);

Man siger, at man foretager et metodekald på objektet, som p refererer til og man skriver: p punktum metodenavn parenteser.

Efter metodekaldet til move(), har x- og y-koordinaterne ændret sig i det objekt, som p peger på.

Et objekt kan indeholde metoder
Et metodekald på et objekt kan ændre objektets data

Til højre er Point-klassen illustreret i UML-notationen.

Herunder er nogle af de metoder, som punktobjekter forstår (en oversigt over klassen kan findes i appendiks, afsnit Fejl: Henvisningskilde ikke fundet).

Nogle af Point-klassens metoder

move(int x, int y)
Sætter punktets koordinater

translate(int x, int y)
Rykker punktets koordinater relativt i forhold til, hvor det er

Først står navnet på metoden med fed, f.eks.: move.

Derefter står parametrene adskilt af komma, f.eks.: (int x, int y).

For hver parameter er angivet en type og et navn. Typen angiver, hvilke værdier man kan kalde metoden med og bruges til at kontrollere, at man har kaldt den med en værdi af den rigtige type. Navnet i beskrivelsen bruges kun til at minde om, hvad parameteren betyder.

Bemærk, at kaldet derfor ser anderledes ud end beskrivelsen:

  p.move(200,300);          // korrekt
  p.move(int 200, int 300); // sprogfejl: parametertyper angivet ved kald.
  p.move(x=200, y=300);     // sprogfejl: parameternavne angivet ved kald.
I parenteserne i metodekaldet giver man oplysninger til objektet om, hvordan man vil have metoden udført
Oplysningerne kaldes parametre (eller argumenter)

I kaldet til move() ovenfor gav vi oplysningerne 200 og 300 som parametre.

3.2.4 Eksempel

Her er et eksempel på tingene, vi har vist ovenfor:

import java.awt.Point; // Point-klassen skal importeres fra pakken java.awt

public class BenytPunkter
{
  public static void main(String[] arg)
  {
    Point p;
    p = new Point();

    int a;

    a = p.x;

    System.out.println("a: "+a);

    System.out.println("1 x-koordinat: "+p.x);
    System.out.println("1 y-koordinat: "+p.y);

    p.x = 110;
    p.y = 210;
    System.out.println("2 x-koordinat: "+p.x);
    System.out.println("2 y-koordinat: "+p.y);

    p.move(200,300);
    System.out.println("3 x-koordinat: "+p.x);
    System.out.println("3 y-koordinat: "+p.y);

    p.x = p.x + 5;
    System.out.println("4 koordinater: "+p.toString()); // se afsnit 0.5.4

    p.translate(-10,20);
    System.out.println("5 koordinater: "+p);            // se afsnit 0.5.5
  }
}

a: 0
1 x-koordinat: 0
1 y-koordinat: 0
2 x-koordinat: 110
2 y-koordinat: 210
3 x-koordinat: 200
3 y-koordinat: 300
4 koordinater: java.awt.Point[x=205,y=300]
5 koordinater: java.awt.Point[x=195,y=320]

3.2.5 Import af standardklasser

Øverst i kildeteksten "importerer" vi alle klasser i pakken java.awt:

import java.awt.Point;

Dette fortæller compileren, hvor den skal lede efter definitionen af klasserne, vi bruger i programmet. I dette tilfælde er det for at compileren skal kende til Point-klassen (der findes i pakken java.awt).

En pakke er en samling klasser med beslægtede funktioner. AWT står for "Abstract Window Toolkit" og java.awt indeholder forskellige nyttige klasser til at tegne grafik på skærmen, herunder klasser til at repræsentere punkter og rektangler.

Lige nu er det nok at vide, at de fleste klasser skal importeres, før de kan bruges (hvis du er meget nysgerrig, kan du læse den første del af kapitel Fejl: Henvisningskilde ikke fundet om pakker allerede nu).

3.3 Rektangler (klassen Rectangle)

Vi vil nu gå videre til nogle lidt mere indviklede objekter af klassen Rectangle. Den bruges sjældent i praksis (så du behøver ikke lære dens metoder udenad), men den er velegnet til at illustrere ideer omkring oprettelse af objekter (konstruktører) og kald af metoder og deres returværdier.

Et rektangel-objekt består af en x- og y-koordinat og en højde og bredde. Disse objektvariabler/felter med data hedder x, y, width og height.

En variabel med navnet r af typen Rectangle erklæres med:

    Rectangle r;

Ligesom med Point skal vi have lavet et rektangel-objekt, som r refererer til, ellers peger r ingen steder hen (den har værdien null):

    r = new Rectangle();

Som med de simple typer kan man godt erklære variablen og initialisere den i samme linje:

    Rectangle r = new Rectangle();




Det Rectangle-objekt, der oprettes, får x, y, width og height sat til 0.

Vi kan ændre dette til (1,1,10,10) med:

    r.x = 1;
    r.y = 1;
    r.width = 10;
    r.height = 10;

Det er besværligt, hvis man skal bruge fire linjers programkode på, at sætte et objekts værdier, når man opretter det. Det kan gøres kortere.

3.3.1 Konstruktører

Når man vil oprette et objekt med bestemte startværdier, kan det gøres ved, at benytte en konstruktør, hvor startværdierne kan angives.

For eksempel kan et rektangel oprettes med:

    r = new Rectangle(1,1,10,10);

De fire parametre i parenteser fortæller, at det rektangel, som skal skabes, som start skal have det øverste venstre hjørne i (1,1) og en bredde og en højde på 10.

Det er i virkeligheden en slags metodekald, vi her foretager, så det er ikke nogen tilfældighed, hvis det ligner.

Når man skaber et nyt objekt med new, kaldes en konstruktør
Konstruktøren opretter objektet og initialiserer dets data (variabler)
Nogle konstruktører har parametre, der beskriver, hvordan objektet skal oprettes (hvilke værdier dets variabler skal have)

Herunder er beskrevet tre konstruktører for Rectangle – dvs. tre måder, rektangler kan oprettes på.

Nogle af Rectangle-klassens konstruktører

Rectangle()
opretter et rektangel i (0,0), hvis bredde og højde er 0

Rectangle(int bredde, int højde)
opretter et rektangel i (0,0) med den angivne bredde og højde

Rectangle(int x, int y, int bredde, int højde)
opretter et rektangel i (x,y) med den angivne bredde og højde

Point-klassens konstruktører er beskrevet i appendikset afsnit Fejl: Henvisningskilde ikke fundet. Vi kan f.eks. bruge den, der har to parametre:

    Point p;
    p = new Point(8,6);  // skaber et Point-objekt med koordinaterne (8,6)

3.3.2 Metoder

Vi vil nu lave et lille program, der tjekker, om punktet p ligger inde i rektanglet r. Vi erklærer en variabel, inde, af type boolean, som vi kan bruge til at gemme resultatet af vores undersøgelse i.

    boolean inde;

Objekter af klassen Rectangle har en metode, contains(), som kan fortælle, om et punkt ligger inde i rektanglet:

    inde = r.contains(p);

Det, der sker, er, at vi kalder metoden contains() – svarende til spørgsmålet "indeholder du p?" – på rektanglet r. Vi giver p med som parameter, således at rektanglets metode ved, at det lige præcis er punktet p, som skal undersøges. Metoden bliver udført og foretager nogle beregninger, som vi ikke kan se og til sidst kommer den ud med et svar. Dette svar returneres til os og bliver gemt i variablen inde. Modsat tilfældet med Point-objekters move()- og translate()-metoder er rektanglers indhold uændret af kald af contains().

Ikke alle metoder på et objekt ændrer på det
Nogle metoder giver et svar tilbage (returnerer et resultat)

Prøv at sammenligne det med kaldet til Math.sqrt(), som vi så i forrige kapitel:

    hypotenuse = Math.sqrt(x*x + y*y);

Det er samme mekanisme: Vi spørger Math.sqrt() om, hvad kvadratroden af x*x+y*y er og svaret, som metoden giver tilbage, gemmer vi i variablen hypotenuse.

3.3.3 Metoders returtype

Ligesom parametre skal være af den rette type, gælder for resultatet af et metode-kald at:

En metode giver et resultat af en bestemt type, når den bliver udført
Dette kaldes metodens returtype

Math.sin() har returtypen double, mens contains() på et rektangel-objekt har returtypen boolean. Det er derfor, vores variabel inde også skulle have typen boolean.

Hvis punktet var inde i rektanglet, så vil vi skrive det på skærmen:

    if (inde==true)
    {
        System.out.println(”p er inde i r”);
    }

Herunder ses nogle af Rectangle-klassens metoder. Foran metode-navnene står returtyperne. I kursiv står spørgsmålene, som de svarer til. En mere komplet oversigt over klassen kan findes i appendiks i afsnit Fejl: Henvisningskilde ikke fundet.

Nogle af Rectangle-klassens metoder.

boolean contains (Point p) "indeholder du p?"
returnerer true, hvis
p er inden for rektanglet, ellers false.

Point getLocation() "hvad er din placering?"

returnerer et Point-objekt, der har samme koordinater som rektanglets øverste venstre hjørne.

String toString() "hvordan vil du beskrive dig selv?"
giver en beskrivelse af rektanglet med (x,y
)-koordinater og mål som en streng.

Her er Rectangle illustreret i UML-notation.





Returtyperne skrives her efter metodenavnet. Ofte vil vi af hensyn til overskueligheden undlade returtyperne (ligesom vi nogle gange undlader parametertyperne).

Herunder ses et samlet eksempel med to punkter. Det andet punkt, p2, undersøger vi direkte i en if-sætning uden at bruge en mellemvariabel.

import java.awt.*;

public class BenytRektangler
{
  public static void main(String[] arg)
  {
    Point p, p2;
    Rectangle r;

    p = new Point();
    p2 = new Point(6,8);
    r = new Rectangle(1,1,10,10);

    boolean inde;
    inde = r.contains(p);
    if (inde==true)
    {
        System.out.println("p er inde i r");
    }

    if (r.contains(p2))
    {
        System.out.println("p2 er inde i r");
    }
  }
}

p2 er inde i r

3.3.4 Metoders parametre

Her er et eksempel, der beregner afstanden (distancen) mellem punktet p og rektanglet r's øverste venstre hjørne. Det foregår ved, at vi kalder r's getLocation()-metode – "hvad er din position?". Svaret bruger vi som parameter til at kalde p's distance()-metode med svaret fra r – "Hvad er din afstand til (svaret fra r)?"

    double afstand;
    afstand = p.distance(r.getLocation());
Ved et metodekald beregnes først alle parametrene og derefter udføres metoden

Dvs. først beregnes parameteren, getLocation() kaldes altså på r. Den returnerer et punkt som er r's (x,y) og derefter kaldes distance() på p med dette Point-objekt som parameter.

Man kunne også bruge en mellemvariabel og skrive:

    Point rpunkt;
    rpunkt = r.getLocation();      // rpunkt er r's øverste venstre hjørne
    afstand = p.distance(rpunkt);

Det er i starten lettere at læse kode med mellemvariabler, men når eksemplerne bliver mere indviklede, bliver antallet af mellemvariabler for stort. Man skal øve sig i selv at forestille sig, at der er nogle mellemregninger med mellemvariabler.

3.4 Indlæsning af tekst med Scanner

Scanner-klassen brugte vi allerede i afsnit Fejl: Henvisningskilde ikke fundet Fejl: Henvisningskilde ikke fundet. Her er dens vigtigste metoder beskrevet.

Nogle af Scanner-klassens metoder

int nextInt() "læs det næste som et helt tal - hvad er det for et tal?"
læse den næste tekst i input som et tal. Der springes over linjeskift og mellemrum.

boolean hasNextInt() "er det næste et helt tal?"
tjekker om den næste tekst i input (linjeskift og mellemrum ignoreret) kan læses som et heltal. Placeringen i input ændres ikke, hvis svaret er true betyder det at nextInt() kan kaldes uden fejl.

double nextDouble() "læs det næste som et kommatal - hvad er det for et tal?"
læser den næste tekst i input som et kommatal. Der springes over linjeskift og mellemrum.

boolean hasNextDouble() "er det næste et kommatal?"

String nextLine() "læs resten af linjen - hvad er det for en tekst?"
fortsætter læsning af input indtil der mødes et linjeskift. Hvis man står lige ved et linjeskift hoppes til næste linje i input

Dette eksempel bruger Scanner til at læse strenge, heltal og kommatal fra brugeren, til at lave statistik over aldre og vægte for personer fra en husstand.

import java.util.Scanner;

public class BenytScanner 
{
  public static void main(String[] arg)
  {
    Scanner scanner = new Scanner(System.in); // opret scanner-objekt
    System.out.println("Hvor mange personer er der i din husstand? ");
    int antalPersoner = scanner.nextInt();

    int sumAlder = 0;
    double sumVægt = 0;
    String alleNavne = "";

    for (int n = 1; n <= antalPersoner; n++) {
      scanner.nextLine();                      // hop over linjeskiftet
      System.out.print("Skriv personen nummer " + n + "s navn og tryk retur: ");
      String navn = scanner.nextLine();        // læs en linje fra tastaturet
      System.out.print("Skriv " + navn + "s alder og vægt og tryk retur: ");
      int alder = scanner.nextInt();           // læs et helt tal fra tastaturet
      double vægt = scanner.nextDouble();      // læs et kommatal fra tastaturet
      if (n>1) alleNavne = alleNavne + ", ";   // sæt komma før næste navn
      alleNavne = alleNavne + navn;
      sumAlder = sumAlder + alder;
      sumVægt = sumVægt + vægt;
    }

    System.out.println("Statistik for " + alleNavne); 
    System.out.println("Gennemsnitlig alder: " + sumAlder / antalPersoner);
    System.out.println("Gennemsnitlig vægt: " + sumVægt / antalPersoner);
  }
}

Hvor mange personer er der i din husstand? 
2
Skriv personen nummer 1s navn og tryk retur: Jacob
Skriv Jacobs alder og vægt og tryk retur: 42 69
Skriv personen nummer 2s navn og tryk retur: Anne Mette
Skriv Anne Mettes alder og vægt og tryk retur: 40 62
Statistik for Jacob, Anne Mette
Gennemsnitlig alder: 41
Gennemsnitlig vægt: 65.5

3.5 Tekststrenge (klassen String)


s refererer
ikke til noget

Vi kommer nu til de mest brugte objekter, nemlig tekststrenge (af typen String). En variabel, der refererer til strenge, erklæres ved at skrive

String s;

Nu har vi defineret, at s er en variabel, der kan referere til objekter af typen String, men den peger endnu ikke på nogen konkret streng.



s refererer nu
til en streng

Lad os tildele s en værdi. Så er situationen som vist på figuren til højre:

s = "Ude godt";

Vi kan bruge s i vores program, f.eks. til at skrive ud på skærmen:

System.out.println("Strengen s indeholder: "+s);

Vi kan spørge streng-objektet om forskellige ting. For eksempel kan vi kalde length(), der svarer til spørgsmålet "hvor lang er du?":

int strengensLængde;
strengensLængde = s.length();  //  strengen svarer med tallet 8
System.out.println("s er "+strengensLængde+" tegn lang");

s er 8 tegn lang 

Vi kunne også springe mellemvariablen over og skrive:

System.out.println("s er "+s.length()+" tegn lang"); 

Metoden toUpperCase() svarer til spørgsmålet "hvordan ser du ud med store bogstaver?":

System.out.println("s med store bogstaver: "+s.toUpperCase());

s med store bogstaver: UDE GODT

Herunder ses nogle af metoderne, man kan kalde på strenge. I kursiv til højre står spørgsmålene, som de svarer til.

Nogle af String-klassens metoder. En mere fuldstændig oversigt kan findes i afsnit Fejl: Henvisningskilde ikke fundet.

String replace (String søgetekst, String erstatning) "hvad hvis x erstattes med y i strengen?"
giver en ny streng, som er identisk med denne streng, bortset fra at alle steder i strengen hvor teksten søgetekst står er blevet erstattet med teksten erstatning.

String substring (int startindeks) "hvad er delstrengen fra x?"
giver en ny streng, som er en del af denne streng. Delstrengen starter ved startindeks og går til slutningen.

String substring (int startindeks, int slutindeks) "hvad er delstrengen fra x til y?"
giver en ny streng, som er en del af denne streng. Delstrengen starter ved startindeks og slutter ved slutindeks (til og med slutindeks-1).

String toLowerCase () "hvordan ser du ud med små bogstaver?"
giver en ny streng, som er identisk med denne streng, bortset fra at alle store bogstaver er erstattet med små.

String toUpperCase () "hvordan ser du ud med store bogstaver?"
giver en ny streng, som er identisk med denne streng, bortset fra at alle små bogstaver er erstattet med store.

boolean equals (String str) "er det samme indhold?"
giver sand, hvis denne streng indeholder den samme tegnsekvens som str, ellers falsk.

int length () "hvad er din længde?"
giver længden af (antal tegn i) strengen.

int indexOf (String str) "hvor er delstrengen x?"
giver indeks på første forekomst af str som delstreng. Er str ikke er en delstreng, returneres -1.

Herunder er et eksempel på brug af nogle af metoderne:

// Viser brugen af String-klassen og dens metoder.
public class BenytStrenge
{
  public static void main(String[] arg)
  {
    String s = "Ude godt";
    System.out.println("Strengen s indeholder: "+s);
    System.out.println("s er "+s.length()+" tegn lang");
    System.out.println("s med store bogstaver: "+s.toUpperCase());
    System.out.println("Tekst på plads nummer 4 og frem: "+s.substring(4));
    System.out.println("Det første g er på plads nummer: "+s.indexOf("g"));
  }
}

Strengen s indeholder: Ude godt
s er 8 tegn lang
s med store bogstaver: UDE GODT
Tekst på plads nummer 4 og frem: godt Det første g er på plads nummer: 4

3.5.1 Streng-objekter er uforanderlige

De fleste objekter tillader, at deres data ændres, enten ved at man direkte har adgang til deres variabler eller gennem kald af metoder.

Når vi skal ændre i et Point-objekt, f.eks. så dets x og y er (1,1), skriver vi:

  p.move(1,1);                // p forandres

Sådan er det ikke med strenge: Metoderne i strenge er indrettet sådan, at de ikke ændrer i objektet. I stedet returneres et nyt streng-objekt, som indeholder resultatet af ændringen.

Kalder man derfor en ændringsmetode på en streng, bliver strengen ikke ændret:

  s.replace("godt", "fint");   // objektet s peger på forandres ikke

replace() giver en anden streng tilbage til os, hvor alle steder med "godt" er erstattet med "fint", men den bliver smidt væk med det samme, da vi ikke bruger returværdien.

I stedet skal vi huske returværdien:

  String s2;
  s2 = s.replace("godt", "fint");// s forandres ikke, men s2 husker resultatet

Nu bliver resultat-strengen gemt vha. s2 (den streng s peger på er som sagt uforandret).

Her ses samlet et eksempel på, hvordan man bruger strenge:

public class BenytStrenge2
{
  public static void main (String[] arg)
  {
    String s1, s2, s3, s4;
    s1 = "Ude godt, men hjemme bedst.";
    s1.toUpperCase();          // lav store bogstaver, men resultatet kasseres
    s2 = s1.toUpperCase();     // lav store bogstaver fra s1, gem det i s2
    s3 = s2.replace("E", "X"); // erstat E med X på s2 og gem resultatet i s3
    s4 = s3.substring(4, 16);  // tag delstreng på s3 og gem resultatet i s4

    System.out.println ("s1: " + s1);  // s1 er stadig med små bogstaver
    System.out.println ("s2: " + s2);  // s2 har ikke fået ændret E til X
    System.out.println ("s3: " + s3);  // s3 er ikke delstrengen på plads 4-16
    System.out.println ("s4: " + s4);  // s4 er delstrengen på plads 4-16
  }
}

s1: Ude godt, men hjemme bedst.
s2: UDE GODT, MEN HJEMME BEDST.
s3: UDX GODT, MXN HJXMMX BXDST.
s4: GODT, MXN HJ

Variablerne s1, s2, s3 og s4 får tildelt en reference (pegepind) til hvert sit strengobjekt og derefter ændrer deres indhold sig ikke, uanset hvilke metoder der kaldes på objekterne.

Bemærk, at selvom streng-objekterne i sig selv er uforanderlige, kan streng-variabler godt ændres:

  s = s.replace('d','f');  // sæt s til at referere resultatet af replace()

Forskellen mellem en metode, der ændrer på det objekt, den bliver kaldt på og en metode, der returnerer en værdi, kan være svær at forstå i starten, men det kommer i takt med, at du programmerer selv.

3.5.2 Oprette String-objekter

De andre klasser, vi har set indtil nu, har vi brugt til at skabe nye objekter med. Når vi skulle lave et nyt Point-objekt, kaldte vi dens konstruktør vha. new, f.eks.:

  Point p = new Point(0,0);

Lige netop med strenge behøves det ikke. Her skriver man typisk:

  String s = "Ude godt";

Man kan godt skrive:

  String s = new String("Ude godt");

I det sidste tilfælde skabes et nyt String-objekt, som også indeholder teksten "Ude godt", så der i lageret er to strenge med samme indhold, hvilket er unødvendigt. Netop fordi strenge ikke kan ændres, når de først er skabt, har man aldrig brug for kopier. Hvorfor skulle man lave en kopi, når den alligevel altid vil være helt den samme som originalen?

3.5.3 Navnesammenfald for metoder/overloading

I tabellen over Strings metoder er der en, der er nævnt to gange; substring(). Den findes i to varianter: substring(int startindeks) og substring(int startindeks, int slutindeks).

Hvilken variant der kaldes i BenytStrenge2.java ved tildelingen af s4, kan man se ud fra hvilke parameterlister, der passer sammen. I dette tilfælde den metode med to parametre.

Så længe der er forskel på antallet af parametre, er det simpelt nok, ellers må man kigge på typerne af parametrene.

3.5.4 Metoden .toString()

Metoden toString() laver en streng-repræsentation af et objekt.

Alle objekter har metoden toString(), der giver en beskrivelse som en streng

Nogle objekter er mere beskrivende end andre.

Et Point-objekt inkluderer både sit fulde klassenavn og sine koordinater i beskrivelsen, f.eks.: java.awt.Point[x=205,y=300]. Det samme gælder Rectangle, der også giver bredden og højden med f.eks: java.awt.Rectangle[x=1,y=1,width=10,height=10].

Senere skal vi se at .toString() på en liste (ArrayList) en beskrivelse af indholdet at listen, og at .toString() på et Date-objekt giver datoen som tekst, f.eks: Tue Sep 25 06:07:46 CEST 2013.

3.5.5 At sætte strenge sammen med +

Operatoren + bruges ikke kun til at lægge tal sammen. Hvis enten højre- eller venstre-siden er en streng, bliver + opfattet som: "konverter begge sider til strenge og sæt dem i forlængelse af hinanden til en samlet streng".

Hvis man f.eks. skriver:

  Point p;
  p=new Point(1,1);
  System.out.println("Svaret er: "+p);

Svaret er: java.awt.Point[x=1,y=1]

Sker der i computeren nogenlunde følgende:

  String s1;
  String s2;
  String s3;
  s1 = "Svaret er: ";
  s2 = p.toString();  // toString() er en metode alle objekter har
  s3 = s1 + s2;
  System.out.println(s3);
Compileren sætter automatisk kode ind, der kalder toString(), hvis den møder et + mellem en streng og en anden slags objekt.

Alle de simple typer kan også laves om til strenge med +:

  int i;
  i = 42;
  System.out.println("Svaret er: "+i);

Java kigger ikke på indholdet af strengene, så "2" (som streng) + 3 (som tal) giver "23" (som streng).

Man kan altså bruge operatoren + til et lille trick: For at få noget repræsenteret som en streng, kan man sammensætte det med en tom streng:

  String s;
  int i;
  i = 42;
  s = ""+i; // nu peger s på strengen "42"

Man kan derimod ikke skrive:

  s = i;   // sprogfejl: konverterer ikke automatisk fra int til String. 

...eller...

  i = s+1; // sprogfejl: konverterer ikke automatisk fra String til int.

... selvom s er "42".

3.5.6 Sammenligning af objekter

Umiddelbart kunne man fristes til at sammenligne to strenge med == ligesom med de simple typer. Det går ofte (men ikke altid!) godt:

    s1 = "Hej verden";
    s2 = s1;
    if (s1 == s2) System.out.println("s1 og s2 er ens.");       // forkert!
    else System.out.println("s1 og s2 er IKKE ens."); 

s1 og s2 er ens.

Men == sammenligner ikke indholdet af objekterne, men referencerne til (adresserne på), objekterne. Sammenligningen s1==s2 er sand, fordi s1 og s2 peger på det samme sted i hukommelsen.

Hvis s1 og s2 refererer til to objekter to forskellige steder i hukommelsen vil s1==s2 være falsk, også selvom objekterne har samme indhold:

    s1 = "Hej verden";
    s2 = "Hej " + s1.substring(4); // giver "Hej "+"verden" = "Hej verden"
    if (s1 == s2) System.out.println("s1 og s2 er ens.");       // forkert!
    else System.out.println("s1 og s2 er IKKE ens."); 

s1 og s2 er IKKE ens.

For at sammenligne objekter bør man i stedet kalde equals()-metoden, dvs. spørge et af objekterne "har du samme indhold som dette objekt?" og give det andet objekt som parameter:

    if (s1.equals(s2)) System.out.println("s1 og s2 er ens.");  // korrekt
    else System.out.println("s1 og s2 er IKKE ens."); 

s1 og s2 er ens.

Dette gælder i virkeligheden ikke kun strenge. Alle objekter har en equals()-metode, som kan bruges til at afgøre, om indholdet af to objekter er ens og den bør bruges fremfor ==.

Sammenligning af adresser på objekter sker med ==
Sammenligning af objekters indhold sker med equals()-metoden

3.5.7 Opgaver

  1. Skriv et program, der finder positionen af det første mellemrum i en streng.
    (vink: Brug metoden indexOf(" "))

  2. Skriv et program, der fjerner det første ord i en sætning (indtil første mellemrum).

  3. Skriv et program, der tæller antallet af mellemrum i en tekst.

  4. Skriv et program, der fjerner den første forekomst af ordet "måske" fra en tekst.
    Ændr derefter programmet, så det fjerner alle forekomster af ordet (brug en løkke).

  5. Skriv et program, der finder og fjerner alle forekomster af ordet "måske" fra en tekst, uanset om det er skrevet med store eller små bogstaver.

  6. Skriv et program, der undersøger, om en tekst er et palindrom, dvs. med samme stavning forfra og bagfra (som f.eks. "regninger", "russerdressur", "vær dog god ræv").
    (vink: Træk de enkelte tegn ud af strengene med substring(n,n+1) og husk, at strengobjekter skal sammenlignes med .equals()-metoden: s1.equals(s2)).

  7. Udvid programmet til at tage højde for store/små bogstaver, tegnsætning og mellemrum, sådan at de følgende palindromer også genkendes: "Selmas lakserøde garagedøre skal samles" og "Åge lo, da baronesse Nora bad Ole gå".

3.6 Lister (klassen ArrayList)

En ArrayList er en liste af objekter, der bliver nummereret efter et indeks.

Konstruktører og metoder er beskrevet i appendiks, i afsnit Fejl: Henvisningskilde ikke fundet.

En ArrayList er en liste af objekter

En liste oprettes med viden om, hvilken slags objekter, den skal indeholde (her String)2:

  ArrayList<String> liste;
  liste = new ArrayList<String>();

Man tilføjer elementer til listen med liste.add( ). Her føjer vi strengen "æh" til listen:

  liste.add("æh");

Man kan sætte ind midt i listen med liste.add( indeks , objekt ):

  liste.add(0,"øh");

Her indsætter vi "øh" på plads nummer 0, sådan at listen nu indeholder først "øh" og så "æh". Alle elementerne fra og med det indeks, hvor man indsætter, får altså rykket deres indeks ét frem.

Man aflæser et element i listen med liste.get( indeks ).

Med liste.size() får man antallet af elementer i listen, i dette tilfælde 2.

Nogle af ArrayList-klassens metoder

Metoder

void add ( element )
Føjer element til listen. element skal være af ArrayList-objektets type.

void add ( int indeks , element )
Indsætter element i listen lige før plads nummer indeks. Første element er på plads nummer 0.

void remove ( int indeks )
Sletter elementet på plads nummer indeks.

int size ()
returnerer antallet af elementer i listen.

Object get ( int indeks )
Returnerer en reference til objektet på plads nummer indeks (regnet fra 0).

String toString ()
returnerer listens indhold som en streng. Dette sker ved, at konvertere hver af elementerne til en streng.

ArrayList-klassen skal importeres med import java.util.ArrayList; før den kan bruges



listen lige efter
indsættelse af "buh"

Her er et lille eksempel:

import java.util.ArrayList;

public class BenytArrayList
{
  public static void main(String[] arg)
  {
    ArrayList<String> liste;         // opret liste-variabel
    liste = new ArrayList<String>(); // opret liste-objekt

    liste.add("æh");                 // føj til listen
    liste.add("bæh");
    liste.add("buh");

    System.out.println("Listen har elementerne "+liste.toString());

    liste.add(2,"og");
    System.out.println("Nu har listen "+liste); // .toString() kaldes implicit

    liste.remove(0);
    System.out.println("Nu har listen "+liste+" og størrelsen "+liste.size());
    System.out.println("På plads nummer 1 er: "+liste.get(1));

    for (String element : liste) {  // gennemløb alle elementerne i listen
      System.out.println("Et element i listen: "+ element);
    }
  }
}

Listen har elementerne [æh, bæh, buh]
Nu har listen [æh, bæh, og, buh]
Nu har listen [bæh, og, buh] og størrelsen 3
På plads nummer 1 er: og
Et element i listen: bæh
Et element i listen: og
Et element i listen: buh

Vi indsætter først tre (referencer til) strenge i listen (se figur). Dernæst lægges "og" ind på plads nummer 2, dvs. efter "bæh" og før "buh". Til sidst fjernes "æh" på plads nummer 0.

Lister kan blive vilkårligt lange. De sørger selv for at reservere mere hukommelse, hvis det bliver nødvendigt.

3.6.1 Gennemløb af lister

Læg mærke til, hvordan man kan gennemløbe en liste:

    for (String element : liste) {
      System.out.println("Et element i listen: "+ element);
    }

Denne specielle syntaks til for-løkken (også kaldet foreach) er beregnet til at gennemløbe alle elementerne i en liste. Den har den generelle form:

    for (Elementtype elementvariabel : liste) kommando;

3.6.2 Eksempel: Eventyrfortælling

Her er et program, der kombinerer forskellige personer og handlinger til et lille eventyr:

import java.util.ArrayList;

public class Eventyr
{
  public static void main(String[] arg)
  {
    ArrayList<String> personer = new ArrayList<String>(); // liste af strenge
    personer.add("De tre små grise");
    personer.add("Ulven");
    personer.add("Rødhætte");

    ArrayList<String> handlinger = new ArrayList<String>();
    handlinger.add("slikker sig om munden");
    handlinger.add("får en idé!");
    handlinger.add("gemmer sig i skoven");

    for (int i=0; i<5; i++) {
      int antalPersoner = personer.size(); // antal personer i listen, dvs 3
      int personNummer = (int) (Math.random()*antalPersoner); // giver 0-2
      String person = personer.get( personNummer );
      String handling = handlinger.get( (int)(Math.random()*handlinger.size()));
      System.out.println(person + " " + handling);
    }
  }
}

Ulven får en idé!
Ulven slikker sig om munden
Rødhætte gemmer sig i skoven
De tre små grise slikker sig om munden
Ulven gemmer sig i skoven

Opgave

Udvid programmet, så eventyret bliver mere interessant.

3.6.3 Eksempel: Punkter i en liste

I det næste eksempel lægges tre Point-objekter ind i en liste og listen gennemløbes, for at finde punktet med den mindste afstand til (0,0) (kaldet origo i matematik).

import java.awt.Point;
import java.util.ArrayList;

public class MindsteAfstand
{
  public static void main(String[] arg)
  {
    ArrayList<Point> punktliste;    // punkt-liste
    Point origo, p1, p2, p3;
    double minDist = 10000;
    punktliste = new ArrayList<Point>();
    origo = new Point(0,0);
    p1 = new Point(0,65);
    p2 = new Point(50,50);
    p3 = new Point(120,10);
    
    punktliste.add(p1);
    punktliste.add(p2);
    punktliste.add(p3);
    
    for (Point p : punktliste)
    {
      double dist;

      dist = origo.distance(p);
      if (dist<minDist)
      {
        minDist=dist;
      }
    }

    System.out.println("Den mindste afstand mellem punkterne "
      + punktliste + " og (0,0) er "+minDist);
  }
}

Den mindste afstand mellem punkterne [java.awt.Point[x=0,y=65], java.awt.Point[x=50,y=50], java.awt.Point[x=120,y=10]] og (0,0) er 65.0

3.6.4 Eksempel: Blanding af kort med ArrayList

I det følgende bruges nogle af de metoder, der er nævnt i appendikset om ArrayList (afsnit Fejl: Henvisningskilde ikke fundet). Dette program blander nogle spillekort (beskrevet som strenge3) i en liste:

import java.util.ArrayList;

public class BlandKort
{
  public static void main(String[] arg)
  {
    ArrayList<String> bunke = new ArrayList<String>();

    // Opbyg bunken
    for (int n=2; n<9; n++)
    {
      bunke.add("ruder"+n);  // ruder
      bunke.add("klør"+n);   // klør
      bunke.add("spar"+n);   // spar
    }

    System.out.println("Før blanding: "+bunke);   // bunke.toString() kaldes
    int antalKort = bunke.size();

    // Bland bunken
    for (int n=0; n<100; n++)
    {
      int nr = (int) (Math.random() * antalKort); // find en tilfældig plads

      String kort = bunke.get(nr);                // tag et kort ud
      bunke.remove(nr);

      nr = (int) (Math.random() * antalKort);
      bunke.add(nr, kort);                        // sæt det ind et andet sted
    }
    
    System.out.println("Efter blanding: "+bunke);
  }
}

Før blanding: [ruder2, klør2, spar2, ruder3, klør3, spar3, ruder4, klør4, spar4,
ruder5, klør5, spar5, ruder6, klør6, spar6, ruder7, klør7, spar7, ruder8, klør8,
spar8]
Efter blanding: [spar3, klør3, ruder7, spar5, spar2, ruder5, ruder6, klør6, spar6, klør5, klør8, ruder2, ruder4, klør7, ruder3, spar8, spar4, ruder8, klør4, klør2, spar7]

Blandingen udføres ved 100 gange at tage et kort fra en tilfældig plads (med get()), fjerne det (med remove()) og flytte det til en anden tilfældig plads (med add() på den nye plads).

3.7 Datoer (klassen Date)

Date-klassen repræsenterer et punkt i tiden (en dato og et klokkeslæt).

For at oprette et dato-objekt, der repræsenterer dags dato og tid, skriver vi:

  Date netopNu;
  netopNu = new Date();                    // dags dato og tidspunkt lige nu

new-operatoren er som bekendt bindeleddet mellem en klasse (f.eks. Date) og et objekt (en konkret dato, f.eks. 24/12 2000 kl. 18:37).

For at oprette en dato, der repræsenterer et andet tidspunkt, kan vi bruge en af de andre konstruktører, der får årstal, måned (regnet fra 0), dag, time og minut.

Undertegnede er født den 1. januar 1971, så min fødselsdag kunne oprettes med:

  jacobsFødselsdag = new Date(71,0,1,12,00); // 1.januar 1971 kl. 12:00

I appendiks Fejl: Henvisningskilde ikke fundet er et udvalg af Date-klassens konstruktører og metoder beskrevet.

Eksemplet nedenfor regner på min fødselsdato og finder ud af, hvornår jeg var halvt så gammel som nu.

// Datoer.java
// Viser brugen af Date-klassen og dens metoder.
import java.util.Date; // Date-klassen er i pakken java.util

public class Datoer
{
  public static void main (String[] arg)
  {
    Date netopNu;
    Date jacob;

    netopNu = new Date();                    // dags dato og tidspunkt lige nu
    jacob = new Date(71,0,1,12,00);          // 1. januar 1971 kl. 12:00

    System.out.println("Dags dato: "+netopNu.toString());
    System.out.println("Jacob blev født "+jacob); // .toString() implicit

    // Lad os regne Jacobs alder ud (i millisekunder)
    long nuMs;
    long jacobMs;
    long alderMs;

    nuMs = netopNu.getTime();
    jacobMs = jacob.getTime();
    alderMs = nuMs - jacobMs;
 
    // Hvornår var han halvt så gammel?
    jacob.setTime(nuMs - alderMs/2);
    System.out.println("Jacob var halvt så gammel "+jacob);
  }
}

Dags dato: Tue Sep 25 06:07:46 CEST 2007
Jacob blev født Fri Jan 01 12:00:00 CET 1971
Jacob var halvt så gammel Sun May 14 09:33:53 CEST 1989

Kaldet jacob.setTime(...) ændrer objektet, så Jacobs fødselsdag blev glemt.

Man kan gøre meget mere med datoer end vist her:

3.7.1 Opgaver

  1. Ret Datoer-programmet sådan, at Jacobs fødselsdato ikke går tabt (opret et tredje objekt, i stedet for at ændre i jacob-objektet).

  2. Skriv et program, der udskriver datoen for i morgen, om en uge og om et år.

  3. Skriv et program, der ud fra en persons fødselsdato udskriver alle fødselsdage, som personen har fejret indtil nu (lav f.eks. en while-løkke, hvor du tæller år frem fra fødselsdatoen og brug metoden before(), til at tjekke, om du er nået frem til nu).

3.8 Test dig selv

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.

3.9 Resumé

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.

3.10 Appendiks

Her finder du en oversigt over de vigtigste klasser og deres vigtigste metoder. En komplet oversigt kan findes på http://docs.oracle.com/javase/7/docs/api/.

3.10.1 Klassen Point

Point repræsenterer et punkt med en x- og y-koordinat.

java.awt.Point – punkter med en x- og y-koordinat – skal importeres med import java.awt.Point;

Variabler

int x

x-koordinaten

int y

y-koordinaten

Konstruktører

Point()

Opretter et punkt i (0,0).

Point(int x, int y)
Opretter et punkt i (x,y).

Point(Point p)
Opretter et punkt med samme (x,y)-koordinater som p.

Metoder

void move(int x, int y)
Sætter punktets koordinater.

void translate(int x, int y)
Rykker punktets koordinater relativt i forhold til, hvor det er.

double distance(Point etAndetPunkt)
Giver afstanden fra punktet til etAndetPunkt.

boolean equals(Object obj)
Undersøger, om punktet har samme koordinater som obj. Returnerer true, hvis det er tilfældet og false, hvis obj ikke er et punkt eller hvis det har andre koordinater.

String toString()
giver en strengrepræsentation af punktet med (x,y)-koordinater
, f.eks. java.awt.Point[x=0,y=0]

3.10.2 Klassen Rectangle

Rectangle repræsenterer et todimensionalt rektangel.

java.awt.Rectangle – todimensionalt rektangel – skal importeres med import java.awt.Rectangle;

Variabler

int x

x-koordinat på øverste venstre hjørne

int y

y-koordinat på øverste venstre hjørne

int width

bredden

int height

højden

Konstruktører

Rectangle()
opretter et rektangel i (0,0), hvis bredde og højde er 0.

Rectangle(int bredde, int højde)
opretter et rektangel i (0,0) med den angivne bredde og højde.

Rectangle(int x, int y, int bredde, int højde)
opretter et rektangel i (x,y) med den angivne bredde og højde
.

Rectangle(Point p)
opretter et rektangel i
p, hvis bredde og højde er 0.

Metoder

void add (Point p)
udvider rektanglet sådan, at det også omfatter punktet
p.

void translate (int x, int y)
rykker rektanglets koordinater relativt i forhold til, hvor det er.

boolean contains (Point p)
returnerer true, hvis
p er inden for rektanglet, ellers false.

boolean intersects (Rectangle r)
returnerer true, hvis rektanglet og
r overlapper.

Rectangle intersection (Rectangle r)
undersøger overlappet (fællesmængden, snitmængden) mellem rektanglet og
r og returnerer et rektangel, der repræsenterer det fælles overlap.

Rectangle union(Rectangle r)
returnerer et rektangel, der repræsenterer foreningsmængden, dvs. det mindste rektangel, der indeholder både
r og dette rektangel.

boolean equals(Object obj)
Undersøger, om rektanglet har samme koordinater og mål som obj. Returnerer true, hvis det er tilfældet og false, hvis obj ikke er et rektangel, eller hvis det har andre koordinater eller mål.

String toString()
giver en streng-repræsentation af rektanglet med (x,y)-koordinater og mål.

3.10.3 Klassen String

Strenge er specielle ved, at de ikke kan ændres, når de først er oprettet.

java.lang.String – tekststrenge

char charAt (int indeks)
returnerer tegnet på det angivne indeks. Indeks tæller fra 0.

String replace (String søgetekst, String erstatning)
Giver en ny streng, som er identisk med denne streng, bortset fra at alle steder i strengen, hvor teksten søgetekst står, er blevet erstattet med teksten erstatning.

String substring (int startindeks)
Returnerer en ny streng, som er en del af denne streng. Delstrengen starter ved startindeks og går til slutningen.

String substring (int startindeks, int slutindeks)
Returnerer en ny streng, som er en del af denne streng. Delstrengen starter ved startindeks og slutter ved slutindeks (til og med slutindeks-1).

String[] split (String regulærtUdtryk)
Deler strengen op efter skilletegnene i regulærtUdtryk og returnerer et streng-array med bidderne. Et par eksempler på brug kan findes sidst i afsnit Fejl: Henvisningskilde ikke fundet og i afsnit Fejl: Henvisningskilde ikke fundet.

String toLowerCase ()
returnerer en ny streng, som er identisk med denne streng, bortset fra at alle store bogstaver er erstattet med små.

String toUpperCase ()
returnerer en ny streng, som er identisk med denne streng, bortset fra at alle små bogstaver er erstattet med store.

String trim ()
returnerer en ny streng, som er identisk med denne streng, bortset fra at alle blanktegn, tabulatortegn, linjeskift etc. er fjernet fra begge ender af strengen.

int length ()
returnerer længden af (antal tegn i) strengen.

int indexOf (String str)
returnerer indekset på den første forekomst af str som delstreng. Hvis str ikke er en delstreng, returneres -1.

int lastIndexOf (String str)
returnerer indekset på den sidste forekomst af
str som delstreng. Hvis str ikke er en delstreng, returneres -1.

boolean startsWith (String str)
returnerer sand, hvis denne streng starter med de samme tegn som str, ellers falsk.

boolean endsWith (String str)
returnerer sand, hvis denne streng slutter med de samme tegn som str, ellers falsk.

boolean equals (String str)
returnerer sand, hvis denne streng har samme indhold som str, ellers falsk.

boolean equalsIgnoreCase (String str)
returnerer sand, hvis denne streng har samme indhold som str, ellers falsk. Der skelnes ikke mellem store og små bogstaver.

To strenge s1 og s2 sammenlignes, ved at kalde s1.equals(s2), ikke med s1==s2 (der sammenligner objektreferencer, j.v.f. afsnit 0.5.6).

3.10.4 Specialtegn i strenge

Visse tegn kan man ikke skrive direkte i tekststrenge i kildeteksten. De er opført herunder:

Ønsket tegn

I kildeteksten skrives

Linjeskift (eng.: newline)

\n

Anførselstegn "

\"

Apostrof '

\'

En omvendt skråstreg \ (eng.: backslash)

\\

Unikode-tegn nummer XXXX

\uXXXX

Tabulator. Bruges sjældent

\t

Bak (eng.: backspace). Bruges sjældent

\b

Vognretur (eng.: carriage return). Bruges sjældent

\r

Unikode-tegn skrives som fire hexadecimale cifre (0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F). F.eks. kan de græske bogstaver findes på "\u0390" til "\u03F3" (det græske pi skrives med "\u03C0") og de kyrilliske tegn findes fra "\u0400" til "\u047F". Unikode-tegntabellen kan findes på http://unicode.org. De fleste udviklingsværktøjer tillader også at man indsætter specialtegnene som de ser ud, via kopier-og-indsæt fra en tegnoversigt.

Eksempler:

System.out.println("Jacob\n\n\n\tNordfaaa\b\blk");

Jacob

  Nordfalk
System.out.println("\t\"At være eller ikke være\n\tdet er spørgsmålet.\"");
System.out.println("\t\t\t\t\t\t\t\t\t\tShakespeare");

  "At være eller ikke være
  det er spørgsmålet."
                    Shakespeare

3.10.5 Klassen Date

Date repræsenterer en tid, dvs. en dato og et klokkeslæt. Se eksempler på brug i afsnit 0.7.

java.util.Date – et tidspunkt – skal importeres med import java.util.Date;

Konstruktører

Date ()
opretter et Date-objekt, som repræsenterer tidspunktet, da det blev oprettet.

Date (long tid_i_millisekunder)
opretter et Date-objekt, som repræsenterer et tidspunkt, der er tid_i_millisekunder efter 1. januar 1970 kl 00:00:00 GMT.

Date (int år, int måned, int dag, int timer, int minutter) (frarådes)
opretter et Date-objekt med det givne tidspunkt. Bemærk, at år regnes fra år 1900 (1997 svarer til år=97) og måned regnes fra 0 (januar svarer til måned=0).

Date (String dato) (frarådes)
opretter et Date-objekt, som repræsenterer det tidspunkt, dato indeholder.

Metoder

long getTime ()
returnerer antal millisekunder siden 1. januar 1970 kl. 00:00:00 GMT repræsenteret af dette Date-objekt.

void setTime (long tid_i_millisekunder)
ændrer dette Date-objekt til at repræsentere et tidspunkt, der er tid_i_millisekunder efter 1. januar 1970 kl. 00:00:00 GMT.

boolean after (Date hvornår)
undersøger, om denne dato er efter hvornår-datoen.

boolean before (Date hvornår)
undersøger, om denne dato er før hvornår-datoen.

String toString ()
returnerer en strengrepræsentation af formen: ugedag mm dd tt:mm:ss åååå (f.eks. Man 5. juli 15:23:18 2000). Denne metode kaldes automatisk, hvis man forsøger at lægge en dato sammen med en streng med +-operatoren.

int getDate () (frarådes)
returnerer dagen i måneden repræsenteret af dette objekt.

void setDate (int dag). (frarådes)
ændrer dagen i måneden til dag. Sættes den til en dag uden for denne måned, opfattes det som om måneden skal ændres tilsvarende, f.eks. vil setDate(32) gå ind i næste måned.

Tilsvarende findes getYear(), setYear(), getMonth(), setMonth(), getHours(), setHours(), getMinutes(), setMinutes(), getSeconds() og setSeconds(). (frarådes)

(frarådes): Disse metoder findes, men er senere frarådet, fordi de ikke understøtter andre kalendere end det gregorianske kalendersystem, der bruges i den vestlige verden. Det betyder dog ikke det store for europæiske programmer.

3.10.6 Klassen ArrayList

ArrayList er en liste af andre objekter. Se afsnit 0.6 for eksempler på brug af ArrayList.

java.util.ArrayList – en liste af objekter – skal importeres med import java.util.ArrayList;

Konstruktører

ArrayList<Elementtype> ()
opretter en tom liste med elementer af klassen Elementtype. <Elementtype> kan udelades.

Metoder

void add( Elementtype element )
føjer element til slutningen af listen. Hvis Elementtype var angivet i konstruktøren skal element være af denne type. Elementtyper som Integer eller Double tillader også autoboxing af den tilsvarende simple type (int hhv. double), dvs. liste=new ArrayList<Integer>() tillader liste.add(5).

void add( int indeks , element )
indsætter element i listen lige før plads nummer indeks. Første element er på plads nummer 0.

Elementtype remove( int indeks )
fjerner elementet på plads nummer indeks og returnerer elementet, der blev fjernet.

boolean isEmpty()
returnerer sand, hvis listen er tom (indeholder 0 elementer).

int size()
returnerer antallet af elementer i listen.

Elementtype get(int indeks)
returnerer en reference til objektet på plads nummer indeks.

boolean contains( objekt )
returnerer sand, hvis objekt findes i listen.

int indexOf( objekt )
returnerer indekset på første forekomst af objekt i listen. Hvis den ikke findes, returneres -1.

String toString ()
returnerer listens indhold som en streng. Dette sker ved at konvertere hver af elementerne til en streng.

Autoboxing

ArrayList kan kun indeholde objekter, så ønsker man at gemme f.eks. nogle tal i en liste, så skal der lavet et objekter, der husker tallene. Java har defineret wrapper-klasser, såsom Integer, Double, Char og Boolean, og konverterer automatisk mellem simple typer og wrapper-klasserne (autoboxing). Det vil sige, at man kan lave en liste af tal med:

    ArrayList<Integer> liste = new ArrayList<Integer>();

    liste.add(8);                        // tilføj element '8' på første plads

    int nummer = liste.get(0);           // aflæs 8-tallet i listen

Et eksempel findes i afsnit 0.11.2.

Bemærk at selvom det kunne virke logisk, kan man altså ikke skrive f.eks. ArrayList<int> for at oprette en liste af int, man skal angive en klasse, f.eks. ArrayList<Integer>.

3.11 Avanceret

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.

3.11.1 Sætte strenge sammen med StringBuilder

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.

3.11.2 Standardmetoder til at arbejde med lister

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.

3.11.3 Lister af simple typer (autoboxing)

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.

3.11.4 Andre slags lister og mængder

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.

3.11.5 Nøgleindekserede tabeller (HashMap)

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.

1p er ikke objektet selv. p er kun en reference (pegepind, pointer) til objektet. Endnu har p ikke nogen værdi (man siger, at den er null, dvs. referencen peger ingen steder hen).

2Fra Java 7 af kan man nøjes med at skrive liste = new ArrayList<>(), men her i bogen skriver vi det fuldt ud for klarheds skyld.

3I et rigtigt program ville de enkelte kort nok være repræsenteret med objekter fra en Kort-klasse, hvor hvert Kort-objekt har felterne farve og værdi.

javabog.dk  |  << forrige  |  indhold  |  næste >>  |  programeksempler  |  om bogen
http://javabog.dk/ - Forord af Jacob Nordfalk.
Licens og kopiering under Åben Dokumentlicens (ÅDL) hvor intet andet er nævnt (79% af værket).

Ønsker du at se de sidste 21% af dette værk (267325 tegn) skal du købe bogen. Så får du pæne figurer og layout, stikordsregister og en trykt bog med i købet.