8
Arrayer






Indexerade variabler, arrayer, vektorer
Statistiska mått
Sortering
Rita polygoner
Objektarrayer
Starta program med argument
Kap 8: Sid 2
I detta kapitel introduceras begreppet array, motsvarigheten till matematikens indicerade variabler
(t.ex. x1, x2, … xi, … xn)
Arrayer av heltal exemplifieras bland annat med sorteringsövningar och med exempel där man ritar polygoner.
Vidare får du skapa arrayer av olika typer av objekt.
Gör övningarna i tur och ordning.
Avsnitten om statistiska mått och sortering kan eventuellt studeras vid senare tillfälle.
Övningarna Rymdskepp, Asteroider och Tarning ligger som grund för kommande övningar.
265338161
© Ove Lundgren
2
Kap 8: Sid 3
Indexerade variabler, arrayer, vektorer
Du deklarerar, som bekant, en vanlig primitiv variabel, t ex en heltalsvariabel, så här:
int i;
17
i
Du har då reserverat plats i minnet för ett heltal som vi refererar till som i.
Variabeln i kan tilldelas heltal, t ex
i = 17;
Ibland behöver man arbeta med många variabler:
17
int i,j,k, m;
i
j
k
m
=
=
=
=
17;
3;
5;
21;
i
3
j
5
k
21
m
I matematiken arbetar du med variabler (x, y ,z,…)
När vi behöver många variabler använder vi ofta indexerade variabler. Exempel:
x1, x2, x3, x4, x5 … De ”nedsänkta” tecknen, 1,2, 3 … kallas index
I de flesta programmeringsspråk kan vi arbeta med sådana indexerade, ”numrerade”, variabler.
En uppsättning indexerade variabler kallas en array, ibland en vektor.
Så här deklarerar man en heltalsarray, vi kallar den a, i Java:
int a[] = new int[5];
a[0]
Talet 5 inom klammer i högerledet dimensionerar arrayen, det vill säga
talet anger att att arrayen ska ha 5 element.
Med den här deklarationen reserveras plats för variablerna
Varje enskild variabel i arrayen, t ex
a[2]
a[3]
a[0], a[1], a[2], a[3] och a[4]
(I matematiken skulle vi förmodligen skriva
a[1]
a0, a1, a2, a3 och a4 )
a[4]
a[2] , kallas alltså ett element i arrayen.
Observera att det första elementet i en java-array alltid har nummer 0 (noll)
265338161
© Ove Lundgren
3
Kap 8: Sid 4
När vi arbetar med indexerade variabler med många element orkar vi inte skriva ut varje element.
I matematiken skriver vi kanske
a0, a1, a2 … ai … a1000
Vi låter indexet representeras av en bokstav (oftast bokstaven i )
På samma sätt gör vi i dataprogram där arrayer används.
Övning: Array
Vi illustrerar det vi hittills har pratat om med ett litet konsolprogram.
Vi utnyttjar Prompt.class som har enkla metoder för inmatning.
(Vi utnyttjade det senast i kapitel 5)
Skriv in programmet. Spara som ArrayTest.java i mappen X\java\Arraytester
class ArrayTest
{
public static void main( String args[] )
{
int a[] = new int[5];
// här deklareras o dimensioneras arrayen
for( int i = 0 ; i < 5 ; i++ )
{
a[i] = Prompt.heltal("Skriv tal nummer " + i);
}
System.out.println("Du matade in dessa tal:");
for(int i=0;i<5;i++)
{
System.out.println("Tal nummer " + i + " är " + a[i]);
}
}
}
Du ser hur det fungerar, eller hur?
Vi deklarerar arrayen a med 5 element som kommer att heta a[0], a[1], a[2], a[3] och a[4]
I den första for-loopen låter vi undan för undan variabeln i anta värdena 0, 1, 2, 3 och 4
Inne i for-loopen kan vi mata in ett värde till a[i], det vill säga till a[0] när loopen körs första varvet, sedan
till a[1] och så vidare…
I den andra for-loopen skriver vi ut de tal som matats in…
Kompilera och kör.
Mata in talen 32, 26, 4711, -99 och 13
(ENTER efter varje….)
Efter sista inmatningen kommer programmet
snällt att skriva ut talen igen…
265338161
© Ove Lundgren
32
a[0]
a[1]
26
a[2]
4711
a[3]
-99
a[4]
13
4
Kap 8: Sid 5
Lägg till dessa rader i programmet (efter den andra for-loopen i main-metoden):
System.out.println("Baklänges:");
for(int i = 4 ; i >= 0 ; i-- )
{
System.out.println("Tal nummer " + i + " är " + a[i]);
}
Inmatade tal skrivs ut baklänges.
Vi har nu exemplifierat med heltalsarrayer. På samma sätt kan vi arbeta med arrayer av flyttal (double), tecken
(char) och logiska värden (boolean). Vi kan även använda arrayer av strängar.
Övning: Array of strings
Gör en kopia av programmet ArrayTest. Kalla den ArrayTest2.java. Spara i X\java\Arraytester
Ändra class-namnet till ArrayTest2
Deklarera a som en array of strings:
String a[] = new String[5];
Ändra i första loopen så att man kan mata in strängar i stället för tal, så här:
for(int i = 0 ; i < 5 ; i++ )
{
a[i] = Prompt.strang("Skriv namn nummer " + i);
}
Byt ut ordet ”tal” mot ”namn” i alla ledtexter. Spara. Kompilera. Kör.
Skriv in strängar i stället för tal, t ex namn ( Kalle, Stina, Olle, Pelle, Johan )
Övning: Slumpa tal
Vi ska experimentera mer med heltalsarrayer. Om vi gör arrayerna större blir det arbetsamt att skriva in tal.
Vi slumpar talen i stället. I programmet nedan slumpas 100 tal. Skriv in.
Spara Slumpa.java i mappen X\java\Arraytester
class Slumpa
{
public static void main( String args[] )
{
int n = 100;
int a[] = new int[n];
// Tal i intervallet 0 – 999 slumpas och skrivs ut på skärmen:
for(int i = 0 ; i < n ; i++)
{
a[i] = (int)( 1000*Math.random() );
System.out.print(a[i]+" ");
}
}
}
Kompilera och provkör!
265338161
© Ove Lundgren
5
Kap 8: Sid 6
Statistiska mått
Antag nu att vi har en mängd tal. De kanske är inmatade. De kanske är hämtade från en fil.
(I vårt fall är talen slumpade till en array!)
Hur gör man för att beräkna talens summa, medelvärde, max- och min-värde?
Övning: Summa-medel-max-min
Detta program är inledningsvis identiskt med föregående. Ett antal tal slumpas till en array och skrivs ut.
Vi tänker oss att dessa tal är det statistiska material som vi ska bearbeta.
Skriv in. Spara Statistik.java i mappen X\java\Arraytester. Kompilera. Provkör:
class Statistik
{
public static void main( String args[] )
{
int n = 100;
int a[] = new int[n];
// Tal i intervallet 0 - 999 slumpas och skrivs ut på skärmen:
for(int i=0;i<n;i++)
{
a[i] = (int)( 1000*Math.random() );
System.out.print(a[i]+" ");
}
int summa, max, min;
double medel;
summa = 0; max = -1; min = 1000;
for(int i=0;i<n;i++)
{
summa = summa +a[i];
if (a[i]>max) max = a[i];
if (a[i]< min) min = a[i];
}
medel = (double)summa/(double)n;
System.out.println(" ");
System.out.println("Summa = " + summa + "
Medel = " + medel);
System.out.println("Max = " + max + "
Min = " + min);
}
}
Variabeln summa är från början 0
Vi loopar genom arrayen och för varje varv adderar vi ett element:
summa = summa + a[i];
Efter loopen ligger på så sätt talens summa i variabeln summa
Om vi då delar med antalet tal, n, bör vi få medelvärdet. Observera att variabeln medel är flyttal.
Variabeln max sätter vi före loopen till ett litet tal (det ska säkert finnas tal i arrayen som är större)
Vi väljer max = -1
För varje element i arrayen kollar vi sedan: Om a[i] är störren än max, ja då blir a[i] det nya max-värdet!
Det vill säga:
if (a[i]>max) max = a[i];
När loopen är slut har vi arrayens största tal lagrad i variabeln max
På ett helt analogt sätt finner vi arrayens minsta tal, min
Observera att min sätts till ett stort tal före loopen.
Det ska säkert finnas tal i arrayen som är mindre. Vi väljer min = 1000
Dessa metoder för att finna summa, medel, max och min är allmängiltiga för all programmering.
265338161
© Ove Lundgren
6
Kap 8: Sid 7
Sortering
Arrayer har en mycket stor betydelse inom databehandling.
De används för att hålla reda på stora datamängder, för att söka och sortera.
Metoden sort()
Java2 har en metod för sortering vid namn sort().
Det är en klassmetod i klassen Arrays i paketet java.util
Övning: Testa Java2-metoden sort
Testa gärna. I programmet Statistik - lägg till:
import java.util.*;
Skriv in dessa rader sist i main()-metoden:
Arrays.sort(a); // här sker sker sorteringen
System.out.println("Talen sorterade:");
for(int i=0;i<n;i++)
{
System.out.print(a[i]+" ");
}
Kompilera och kör (Java2)
Skriv en egen sorteringsmetod
Det finns många olika algoritmer för att sortera, mer eller mindre effektiva. Nästa övning visar ett sätt.
Först något om hur man får variabelvärden att ”byta plats” (vilket behövs i alla sorteringsalgoritmer)
Att låta två variabler byta värde (innehåll)
Antag att du har följande:
I variabeln x finns ett tal (t ex 17).
I variabeln y finns ett annat tal (t ex 82)
Vi vill byta plats så att talet i variabeln x hamnar i y, och talet i y hamnar i x.
Vilka satser skriver vi då?
17
Försök med
x = y;
x
y = x;
82
y
Vad händer?
x får först värdet 82 vilket är OK. Men i nästa sats får y värdet av x, vilket ju nu är 82.
Båda varaiblerna får samma värde!
Nytt försök: Inför en ”slaskvariabel”, s, för tillfällig lagring av ett tal.
s = x;
x = y;
y = s;
Nu fungerar bytet!
s
y
x
x
17
82
82
s
y
x
© Ove Lundgren
17
17
82
265338161
17
82
17
Satser:
y
s
7
Kap 8: Sid 8
Övning: Sortera heltal
Ta fram din klass, Matte (kapitel 2 och 7) och skriv in denna metod, sortera()
public static int[] sortera(int[] a, int n)
{
int s;
for(int i = 0; i < n-1 ; i++ )
{
for(int j = i+1; j < n ; j++ )
{
if (a[i] > a[j]) // om a[i] > a[j] byter de plats!
{
s = a[i]; a[i] = a[j]; a[j] = s;
// s är slaskvariabel
}
}
}
return a;
}
Metoden har heltalsarrayen a och ett heltal, n (= antal elemenet i arrayen) som parametrar.
s är ”slaskvariabeln” som används vid sorteringen
Loopen är en så kallad nästlad loop:
En ”yttre” for-loop med i som loopvariabel och en ”inre” med j som loopvariabel.
I denna nästlade loop sker sorteringen:
Looparna tillser att alla element i arrayen jämförs med alla andra element.
Om ett element är större än ett annat låter man elementen byta plats.
När hela arrayen gåtts igenom ligger talen sorterade…
Sist i metoden returneras arrayen a, nu sorterad…
Spara Matte.java och kompilera
I programmet Statistik ovan – lägg till dessa rader sist i main()-metoden:
Matte.sortera(a,n); // Sortering sker
System.out.println("Talen sorterade:");
for(int i=0;i<n;i++)
{
System.out.print(a[i]+" ");
}
Spara – kompilera – kör…
Anmärkning
För att det hela ska fungera måste förstås programmet hitta klassen Matte :
Filen Matte.class ska ligga i samma mapp som Statistik-programmet
eller
Filen Matte.class ska ligga i en mapp som ingår i din classpath-lista
eller
Om Matte.class ingår i ett paket (t.ex. mittpaket) ska du importera det paketet.
265338161
© Ove Lundgren
8
Kap 8: Sid 9
Rita polygoner
När man vill skapa en array med få element kan man använda ett kort skrivsätt för att deklarera och
dimensionera arrayen samt tilldela elementen värden - allt i ett enda svep.
Vår heltalsarray, a, som vi träffade på tidigt i detta kapitel, skulle exempelvis kunna deklarerars, dimensioneras
och ”fyllas på” så här:
int a[] = { 32 , 26 , 4711 , -99 , 13 };
Vi ska utnyttja detta sätt att skapa arrayer i nedanstående övning.
Övning: Polygoner
I tidigare övningar har du lärt dig hur man ritar rektanglar och ovaler med hjälp av grafikobjketets metoder.
Här kommer ännu en metod, drawPolygon() med vars hjälp vi ritar polygoner (månghörningar)
Som argument ska metoden ha två arrayer och ett heltal.
Den första arrayen ska innehålla x-koordinater för polygonens hörn.
Den andra arrayen ska innehålla y-koordinater för polygonens hörn.
Heltalet ska ange antalet hörn.
Nedan deklarerar vi arrayerna x och y. Dessa används sedan som argument då metoden drawPolygon()
anropas.
import java.applet.*;
import java.awt.*;
public class Poly extends Applet
{
int x[] = { 100, 200, 150 };
int y[] = { 100, 120, 50 };
public void paint(Graphics g)
{
g.setColor(Color.red);
g.drawPolygon( x, y, 3 );
}
}
Skriv av koden. Spara som Poly.java i mappen X\java\Polygon Kompilera.
Skapa en html-fil som startar appleten. Kör!
150 , 50
En triangel visas…
100 , 100
200 , 120
Byt sedan ut metoden drawPolygon mot fillPolygon
Triangeln visas fylld…
Rita ytterligare polygoner med fler hörn…
265338161
© Ove Lundgren
9
Kap 8: Sid 10
Övning: Rymdskepp
Skriv en klass, Rymdskepp, med följande egenskaper:
Ett objekt, rs, instansieras med t.ex rs = new Rymdskepp(40,60);
Det ska finnas en metod, public void setPosition(int x, int y){...}
där man, vid anrop, kan ange koordinaterna för skeppets spets, t.ex.
rs.setPosition(100,120);
Det ska finnas en metod, public void visa(Graphics g){...}
Då metoden anropas, t.ex. så här
rs.visa(g);
ska skeppet visas som en ljusgrå ( Color.lightGray) liksidig triangel som har basen 40 och höjden 60
pixels. Skeppets spets ligger i punkten (100,120)
Från skeppets spets ska det vara en mörkgrå ( Color.darkGray ) linje i rät vinkel mot basen.
Instansvaraibler:
private int bredd, hojd, xpos, ypos
( xpos, ypos)
hojd
(xpos-bredd/2, ypos+hojd)
(xpos+ bredd/2, ypos+hojd)
bredd
Spara Rymdskepp.java i mappen X\java\Asteroid
Skriv också en applet, VisaRymdskepp, som instansierar och visar ett Rymdskepp-objekt mot svart
bakgrund.
Skriv också html-filen som visar appleten…
Lösningsförslag på nästa sida…
265338161
© Ove Lundgren
10
Kap 8: Sid 11
// Rymdskepp.java
import java.awt.*;
public class Rymdskepp
{
private int xpos;
private int ypos;
private int bas;
private int hojd;
public Rymdskepp(int b, int h )
{
bas = b;
hojd = h;
}
public void setPosition(int x, int y)
{
xpos = x;
ypos = y;
}
public void visa(Graphics g)
{
int x[] = { xpos, xpos-bas/2, xpos+bas/2};
int y[] = { ypos, ypos+hojd, ypos+hojd };
g.setColor(Color.lightGray);
g.fillPolygon( x, y, 3 );
g.setColor(Color.darkGray);
g.drawLine(xpos,ypos,xpos, ypos+hojd);
}
}
// VisaRymdskepp.java
import java.applet.*;
import java.awt.*;
public class VisaRymdskepp extends Applet
{
Rymdskepp r;
public void init()
{
r =new Rymdskepp(40,60);
r.setPosition( 200,200 );
setBackground(Color.black);
}
public void paint(Graphics g)
{
r.visa( g );
}
}
265338161
© Ove Lundgren
11
Kap 8: Sid 12
Objektarrayer
Precis som vi kan arbeta med arrayer bestående av primitiva variabler kan vi arbeta med arrayer av objekt.
Vi exemplifierar med knappar:
En ”ensam” knapp deklareras med
och instansieras med
Button minKnapp;
minKnapp = new Button(”Tryck på mej!”);
En array of buttons deklareras med
(10 element)
Button minKnapp[] = new Button[10];
Sen måste varje knappobjekt instansieras.
Om möjligt lägger vi instansiering (och utplacering i appleten) i en loop:
for(int i = 0 ; i < 10 ; i++)
{
minKnapp[i] = new Button("" + i);
add( minKnapp[i] );
}
Övning: Array of buttons
A. Spara nedanstående program som ButtArr.java i mappen X\java\ButtArr
Skriv också en html-fil (ButtArr.html) som anropar appleten.
Kompilera och kör:
import java.applet.Applet;
import java.awt.*;
public class ButtArr extends Applet
{
//deklarerar array of buttons:
Button butt[] = new Button[10];
public void init()
{
for(int i = 0 ; i < 10 ; i++)
{
butt[i] = new Button(" " + i + " ");
add( butt[i] );
}
}
}
B. Ändra i koden och ändra appletens storlek så att knapparna ligger så här:
265338161
© Ove Lundgren
12
Kap 8: Sid 13
Övning: Veckodagsknappar
I övningen nedan ska du göra en applet som visar sju knappar. Knapparna ska ha veckodagarnas namn.
Skapa då en string-array med dagarnas namn så här:
String s[] = { "Måndag" , "Tisdag" , "Onsdag" , "Torsdag" ,
"Fredag" , "Lördag" , "Söndag" };
Koden liknar för övrigt koden i föregående exempel.
import java.applet.Applet;
import java.awt.*;
public class Dagknappar extends Applet
{
//deklarerar array of buttons:
Button dagknapp[] = new Button[7];
String s[] = { "Måndag" , "Tisdag" , "Onsdag" , "Torsdag" ,
"Fredag" , "Lördag" , "Söndag" };
public void init()
{
for(int i = 0 ; i < 7 ; i++)
{
dagknapp[i] = new Button(s[i]);
add( dagknapp[i] );
}
}
}
Spara Dagknappar.java i
265338161
X\java\Dagknappar
© Ove Lundgren
13
Kap 8: Sid 14
Övning: Asteroider
I kapitel 4 skrev du klassen Asteroid. Ta fram filen Asteroid.java !
Vi lägger in ännu en konstruktor så att asteroidens storlek och läge slumpas fram.
Ändra (början på) klassen Asteroid så att den ser ut så här:
import java.awt.*;
public class Asteroid
{
private int xpos, ypos, diam;
private Color c1 = new Color(220,220,150 );
private Color c2 = new Color(255,255,190 );
public Asteroid() // ny konstruktor utan parametrar
{
diam = (int) ( Math.random()*20 )+ 10; // diametern blir 10 – 29 pix
xpos = (int)(Math.random()*300);
// placering i x-led 0 - 299
ypos = (int)(Math.random()*300);
// placering i x-led 0 - 299
}
public Asteroid( int d )
{
diam = d;
}
//
Metoderna
setPosition() och visa() ska vara kvar oförändrade
}
Skriv en applet, VisaAsteroider.java som skapar en array av Asteroid-objekt. Lösningsförslag:
// VisaAsteroider.java
import java.applet.*;
import java.awt.*;
public class VisaAsteroider extends Applet
{
Asteroid ast[] = new Asteroid[10];
int a, b, s;
public void init()
{
for(int i=0;i<10;i++)
{
ast[i]=new Asteroid();
}
setBackground(Color.black);
}
public void paint(Graphics g)
{
for(int i=0; i<10; i++) ast[i].visa( g );
}
}
265338161
© Ove Lundgren
14
Kap 8: Sid 15
Övning: Tarning
Kommer du ihåg klassen Tarning (Kapitel 7) ?
Skriv en applet, Yatzi.java, som instansierar fem stycken tärningsobjekt.
När man trycker på en knapp ska tärningarna kastas och visa nya värden.
Så här kan appleten se ut:
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class Yatzi extends Applet implements ActionListener
{
Tarning t[] = new Tarning[5];
Button butt;
int k;
public void init()
{
for (int i = 0; i < 5; i++)
{
t[i]=new Tarning(40, 60*i + 40);
}
k = t[i].kasta();
butt = new Button("Kasta!");
butt.addActionListener(this);
add(butt);
}
public void paint(Graphics g)
{
for(int i = 0;i<5;i++) t[i].visa(g);
}
public void actionPerformed(ActionEvent e)
{
for(int i = 0;i<5;i++) k = t[i].kasta();
repaint();
}
}
Spara – kompilera – provkör!
265338161
© Ove Lundgren
15
Kap 8: Sid 16
Starta program med argument
Argumenten i main-metoden
I kapitel 1 lärde du dig hur ett javaprogram ser ut. Det är en klass som innehåller metoden main.
Så här:
class MittProgram
{
public static void main( String args[] )
{
// kod
}
}
Vid kommandot (från DOS-prompten)
java MittProgram
sker anropet
MittProgram.main();
varvid det som är definierat i main-metodens utförs…
(Repetera gärna början på kapitel 1 och avsnittet om klassmetoder i kapitel 2)
Som du ser är main-metoden definierad med en parameter, en array av typen String
Det betyder att man "skicka med " argument (av typen String) när man startar ett javaprogram.
Ovning: Testa programstart med argument
A.
Skriv in detta program, spara det som ArgsTest.java i X\java\Javagrunder och kompilera:
class ArgsTest
{
public static void main( String args[] )
{
String txt1, txt2;
txt1 = args[0];
txt2 = args[1];
System.out.print( txt1 + " " + txt2 );
}
}
Vi har deklarerat två String-objekt, txt1 och txt2.
Dessa får värdet av angivna argument och skriv ut.
Starta konsolprogrammet från DOS-prompten så här:
java ArgsTest Stina Olle
Programmet skriver ut de angivna argumenten…
265338161
© Ove Lundgren
16
Kap 8: Sid 17
B.
Skriv in, spara, kompilera följande program:
class ArgsTest2
{
public static void main( String args[] )
{
int n = Integer.parseInt( args[1] );
for (int i=0; i < n; i++) System.out.println( args[0] );
}
}
Starta programmet med ( t ex )
java ArgsTest2 Kalle 10
Programmet skriver ut den angivna strängen angivet antal gånger…
265338161
© Ove Lundgren
17