EDAA20 / TFRG65
Programmering och databaser
Föreläsning 9 – Filer & vektorer av objekt
2020-09-28, Niklas Fors, @Zoom
Programmering F föreläsningar, L datorlaborationer (obligatoriska), R resurstid
v43
19/10-23/10
Instuderings- vecka
Tenta, måndag 26 oktober v44
Klassen Scanner för att läsa in saker
public class SumNumbers {
public static void main(String[] args) { Scanner scan = new Scanner(System.in);
int sum = 0;
while (scan.hasNextInt()) { sum = sum + scan.nextInt();
}
System.out.println("Summa: " + sum);
} }
Vi har hittills i kursen använt Scanner-klassen för att läsa in saker från
terminalfönstret
• Läsa in från terminalfönstret:
Scanner scan = new Scanner(System.in);
• Läsa in från fil:
Scanner scan = new Scanner(new File("filnamn"));
• Läsa in från en sträng:
Scanner scan = new Scanner("1 23 34 56");
Klassen Scanner för att läsa in saker
Scanner för att läsa in från fil
public class SumNumbersFromFile {
public static void main(String[] args) { Scanner scan = null;
try {
scan = new Scanner(new File("numbers.txt"));
} catch (FileNotFoundException e) {
System.out.println("Filen kunde inte öppnas");
System.exit(1);
}
int sum = 0;
while (scan.hasNextInt()) { sum = sum + scan.nextInt();
}
System.out.println("Summa: " + sum);
scan.close();
} }
Vi kan också använda Scanner-klassen för att läsa in saker från en fil. Då måste vi hantera om filen inte finns.
Klassen Scanner för att läsa in saker från fil
public class SumNumbersFromFile {
public static void main(String[] args) { Scanner scan = null;
try {
scan = new Scanner(new File("numbers.txt"));
} catch (FileNotFoundException e) {
System.out.println("Filen kunde inte öppnas");
System.exit(1);
}
int sum = 0;
while (scan.hasNextInt()) { sum = sum + scan.nextInt();
}
System.out.println("Summa: " + sum);
scan.close();
} }
Vi kan också använda Scanner-klassen för att läsa in saker från en fil. Då måste vi hantera om filen inte finns.
1) Öppna filen, skriv ut felmeddelande om filen ej finns och avbryt programmet
2) Läs in heltal och summera, precis som tidigare. Därefter skriv ut summan
3) Stäng filen
Klassen Scanner för att läsa in saker från fil
public class SumNumbersFromFile {
public static void main(String[] args) { Scanner scan = null;
try {
scan = new Scanner(new File("numbers.txt"));
} catch (FileNotFoundException e) {
System.out.println("Filen kunde inte öppnas");
System.exit(1);
}
int sum = 0;
while (scan.hasNextInt()) { sum = sum + scan.nextInt();
}
System.out.println("Summa: " + sum);
scan.close();
} }
Vi kan också använda Scanner-klassen för att läsa in saker från en fil. Då måste vi hantera om filen inte finns.
Variabeln måste deklareras innan och utanför try-satsen, så att den kan användas efter try-satsen om filen öppnas.
Java kräver i detta fall att vi tilldelar variabeln ett värde, även om vi kan se att det inte behövs i detta fall (då
programmet stängs av om vi inte lyckas öppna filen).
try-catch-sats
• Ibland inträffar fel och då kan man hantera det med en try-catch-sats:
try {
// Försök göra något där fel kan inträffa } catch (<Typen på felet> e) {
// Felhantering om felet inträffar,
// exempelvis skriv ut felmeddelande och avbryt programmet // Använd variabeln e för att få fram information om felet }
• Om felet inträffar avbryts exekveringen i try-satsen och exekveringen övergår till catch-satsen.
• Detta kallas Exceptions / Exception-hantering
Snabbreferensen
Klassen PrintWriter för utskrift till fil
public class PrintSquareRoots {
public static void main(String[] args) { PrintWriter out = null;
try {
out = new PrintWriter(new File("utdata.txt"));
} catch (FileNotFoundException e) {
System.out.println("Filen kunde inte öppnas");
System.exit(1);
}
// Använd out som System.out, dvs, out.println("text") osv out.close(); // stäng filen, så skrivs innehållet till filen }
}
Klassen PrintWriter för utskrift till fil
public class PrintSquareRoots {
public static void main(String[] args) { PrintWriter out = null;
try {
out = new PrintWriter(new File("utdata.txt"));
} catch (FileNotFoundException e) {
System.out.println("Filen kunde inte öppnas");
System.exit(1);
}
for (int i = 1; i <= 100; i++) { out.println(Math.sqrt(i));
}
out.close(); // stäng filen, så skrivs innehållet till filen }
}
Programmet räknar ut kvadratroten av 1, 2, 3, …, 100 och skriver ut resultaten till
filen utdata.txt
Repetition av vektorer
• Deklarera och skapa vektor:
int[] v = new int[5];
• Användning av vektor:
for (int i = 0; i < v.length; i++) { v[i] = scan.nextInt();
}
v är en referensvariabel som
kan referera till en int-vektor En vektor med storlek 5 skapas, där alla element är av typen int
v.length ger vektorns storlek v[index] för elementåtkomst
index ska vara mellan 0 och v.length-1
Vektorer är objekt
Vektorer i Java är objekt. Referensvariabeln v refererar till vektorn
v
0 0 00 1 2
0 0
3 4
Övning, vektorer
Vad händer i detta exempel? Hur många vektorer skapas? Vad refererar b till? Komplettera bilden.
int[] a = new int[3];
a[0] = 7;
a[1] = 8;
a[2] = 9;
int[] b = a;
a
7 8 90 1 2
Övning, vektorer
Vad händer i detta exempel? Hur många vektorer skapas? Vad refererar b till? Komplettera bilden.
int[] a = new int[3];
a[0] = 7;
a[1] = 8;
a[2] = 9;
int[] b = a;
Enbart en vektor skapas och b refererar till den också.
a
7 8 90 1 2
b
Två vektorer
Hur skapar vi en till vektor med samma innehåll som vektorn a refererar till?
7
a
8 9
0 1 2
b
7 8 90 1 2
Kopiera vektor
7
a
8 9
0 1 2
b
7 8 90 1 2
Hur skapar vi en till vektor med samma innehåll som vektorn a refererar till?
int[] a = new int[3];
a[0] = 7;
a[1] = 8;
a[2] = 9;
int[] b = new int[a.length];
for (int i = 0; i < a.length; i++) { b[i] = a[i];
}
Vi skapar en ny vektor med samma storlek och kopierar element för element.
Genvägar (överkurs)
• Skapa vektor när man vet innehållet:
int[] a = {7, 8, 9};
• Få en kopia av en vektor a:
int[] b = Arrays.copyOf(a, a.length);
• Skriv ut innehållet av en vektor a:
System.out.println(Arrays.toString(a));
Övning: Vad skrivs ut?
public class ArrayExercise {
public static void main(String[] args) { int[] v = new int[2];
v[0] = 1;
v[1] = 2;
m(v);
System.out.println(v[0]);
}
public static void m(int a[]) { System.out.println(a[0]);
a = new int[2];
a[0] = 3;
a[1] = 4;
} }
Vektor av objekt
public class FiveDice {
public static void main(String[] args) { Dice[] dices = new Dice[5];
// Skapa tärningarna
for (int i = 0; i < dices.length; i++) { dices[i] = new Dice();
}
// Kasta tärningarna
for (int i = 0; i < dices.length; i++) { dices[i].roll();
System.out.println("Tärning pos " + i + " visar " + dices[i].getDots());
} } }
Vi kan skapa en vektor av objekt! (Eller snarare en vektor av referensvariabler)
Programmet skapar 5 tärningar och kastar dem
Lagra objekt i vektorer
• Skapa vektorn dices med plats för 5 Dice-objekt:
Dice[] dices = new Dice[5];
• Varje vektorelement är en referensvariabel av typen Dice
• Notera att vi inte har skapat Dice-objekten än, utan enbart en vektor med plats för 5 referensvariabler som inte pekar på något (null)
dices
null null null0 1 2
null null
3 4
Skapa objekten i vektorn
• Skapa objekten dit referensvariablerna ska referera till
for (int i = 0; i < dices.length; i++) { dices[i] = new Dice();
}
dices
0 1 2 3 4
side 6
... ...
side 6
... ...
side 6
... ...
side 6
... ...
6 side
... ...
Klassen Triangle
Implementera klassen Triangle med följande specifikation:
/** Skapar en triangel med hörnpunkterna x1 y1, x2 y2 och x3 y3. */
Triangle(int x1, int y1, int x2, int y2, int x3, int y3);
/** Flyttar triangeln dx i x-led och dy i y-led. */
void move(int dx, int dy);
/** Ritar triangeln i fönstret w. */
void draw(SimpleWindow w);
Program som använder Triangle
public class TriangleExample {
public static void main(String[] args) {
Triangle t = new Triangle(10, 150, 50, 10, 90, 120);
SimpleWindow w = new SimpleWindow(200, 200, "Triangel");
t.draw(w);
t.move(20, 20);
t.draw(w);
} }
Vilka attribut ska klassen Triangle ha?
• Hur ska vi hålla reda på hörnen?
• 6 st attribut med typen int: x1, y1, x2, y2, x3, y3?
• 3 st attribut med typen Point: p1, p2, p3?
• 1 vektor med tre punkter?
• Vi väljer den tredje varianten. Det finns en färdig klass Point i paketet java.awt. Vi kommer att använda dessa metoder:
double getX();
double getY();
void translate(int dx, int dy); // flyttar punkten dx
// längs x-axeln och
// dy längs y-axeln
Klassen Triangle
Implementera klassen Triangle med följande specifikation:
/** Skapar en triangel med hörnpunkterna x1 y1, x2 y2 och x3 y3. */
Triangle(int x1, int y1, int x2, int y2, int x3, int y3);
/** Flyttar triangeln dx i x-led och dy i y-led. */
void move(int dx, int dy);
/** Ritar triangeln i fönstret w. */
void draw(SimpleWindow w);
Konstruktorn
public class Triangle {
private Point[] vertices;
/** Skapar en triangel med hörnpunkterna x1 y1, x2 y2 och x3 y3. */
public Triangle(int x1, int y1, int x2, int y2, int x3, int y3) { vertices = new Point[3];
vertices[0] = new Point(x1, y1);
vertices[1] = new Point(x2, y2);
vertices[2] = new Point(x3, y3);
} ...
}
Konstruktorn skapar både vektorn och Point-objekten
Attributet vertices
Vektor av referensvariabler
vertices
0 1 2
x 90
y 150
x 50
y 10
x 10
y 150
Metoden move
public class Triangle {
private Point[] vertices;
...
/** Flyttar triangeln dx i x-led och dy i y-led. */
public void move(int dx, int dy) {
for (int i = 0; i < vertices.length; i++) { vertices[i].translate(dx, dy);
} } ...
}
Gå igenom vektorn med punkter och anropa metoden translate på varje punkt
Metoden draw
public class Triangle {
private Point[] vertices;
...
/** Ritar triangeln i fönstret w. */
public void draw(SimpleWindow w) {
// använd w.moveTo och w.lineTo
} ...
}
Flytta först till sista
punkten, därefter ritar vi ett sträck till punk 0, till punkt 1, till punkt 2.
vertices[2]
vertices[1]
vertices[0]
Metoden draw
public class Triangle {
private Point[] vertices;
...
/** Ritar triangeln i fönstret w. */
public void draw(SimpleWindow w) {
w.moveTo((int) Math.round(vertices[2].getX()), (int) Math.round(vertices[2].getY()));
w.lineTo((int) Math.round(vertices[0].getX()), (int) Math.round(vertices[0].getY()));
w.lineTo((int) Math.round(vertices[1].getX()), (int) Math.round(vertices[1].getY()));
w.lineTo((int) Math.round(vertices[2].getX()), (int) Math.round(vertices[2].getY()));
} ...
}
vertices[2]
vertices[1]
vertices[0]
Flytta först till sista
punkten, därefter ritar vi ett sträck till punk 0, till punkt 1, till punkt 2.
Metoden draw
public class Triangle {
private Point[] vertices;
...
/** Ritar triangeln i fönstret w. */
public void draw(SimpleWindow w) {
w.moveTo((int) Math.round(vertices[2].getX()), (int) Math.round(vertices[2].getY()));
for (int i = 0; i < vertices.length; i++) {
w.lineTo((int) Math.round(vertices[i].getX()), (int) Math.round(vertices[i].getY()));
} } ...
}
vertices[2]
vertices[1]
vertices[0]
Använd en for-sats istället för att upprepa koden!
Flytta först till sista
punkten, därefter ritar vi ett sträck till punk 0, till punkt 1, till punkt 2.