(22 februari 2016 F6.1 ) Dagens text ArrayList-exempel. Instickssortering. Lite mer om strängar Metoden format i som klassmetod i klassen String som instansmetod i klassen PrintStream (som System.out är) Läsning från filer.
(22 februari 2016 F6.2 ) Repetition ArrayList ArrayList som arrayer men annan syntax (metoder i stället för []) dynamisk dvs kan växa krympa vid behov endast objektreferenser inte primitiva datatyper Konstrueras med ArrayList<E>() ArrayList<E>(int storlek)
(22 februari 2016 F6.3 ) Klassen ArrayList Metoder: add(e e) add(int index, E e) boolean contains(e e) E get(int index) int size() E set(int index, E e) E remove(int index) boolean remove(e e)
(22 februari 2016 F6.4 ) Klassen ArrayList Vad hade blivit annorlunda om ni använt en arraylist i klassen Measurements? Metoden add hade blivit lättare. Måste lagra Double i stället för double (mer plats, mer tid) Övrigt bara syntaktiska ändringar Bra att veta att arraylistor är implementerade med arrayer har betydelse för kostnaden för olika operationer.
(22 februari 2016 F6.5 ) Exempel: Klassen SortedMeasurements Antag att vi i klassen Measurements vill ha en metod som returnerar medianen av de lagrade värdena samt att det inte spelar någon roll i vilken ordning värdena lagras. Anmärkning: Metoden smooth blir antagligen meningslös Vi ska använda en ArrayList i stället för en en array.
(22 februari 2016 F6.6 ) Klassen SortedMeasurements /** * Demonstrates how to keep an arraylist sorted. */ import java.util.arraylist; public class SortedMeasurements { private ArrayList<Double> thevalues; public SortedMeasurements() { thevalues = new ArrayList<Double>(); Observera att vi behöver inte längre hålla reda på antalet element En undran: Behöver man göra en klass när man bara har en enda instansvariabel?
(22 februari 2016 F6.7 ) Klassen SortedMeasurements /** Adds a value to the arraylist keeping it sorted */ public void add(double value) { int i=0; while (i<thevalues.size() && value >= thevalues.get(i)) { i++; thevalues.add(i, value); Observera: 1. Metoden förutsätter att redan lagrade värden är sorterade, 2. Ordningen på de två villkoren i while-satsen. Det går inte att skriva while (value >= thevalues.get(i) && i<thevalues.size() ) {
Klassen SortedMeasurements /** Returns the median of the stored elements */ public double median() { int n = thevalues.size(); if (thevalues.size()==0) { // if no elements return Double.NaN; else if (n%2==1) { // if odd number return thevalues.get(n/2); else { // if even number return (thevalues.get(n/2-1) + thevalues.get(n/2))/2.; Observera: 1. Konstanten Double.NaN 2. Medianen vid ett jämnt antal element kan definieras ibland som ett av de två mittersta elementen. (22 februari 2016 F6.8 )
(22 februari 2016 F6.9 ) Klassen SortedMeasurements public String tostring() { return thevalues.tostring(); public static void main(string[] args) { SortedMeasurements m = new SortedMeasurements(); for (int i=0; i<5; i++) { m.add(math.random()); System.out.println("Output using tostring() :\n" + m + "\n"); Ger utskriften Output using tostring() : [0.34445594204264907, 0.34957658659203494, 0.43230426828775326, 0.5435901121816705,
(22 februari 2016 F6.10 ) Klassen SortedMeasurements Snyggare utskrift med public void print() { for(int i=0; i<thevalues.size(); i++) { System.out.format("%6.2f", thevalues.get(i)); if (i%10==9) { System.out.println(); Med 20 lagrade värden kan utskriften se ut på detta sätt: 0,03 0,04 0,06 0,08 0,12 0,15 0,23 0,25 0,37 0,41 0,42 0,46 0,55 0,56 0,62 0,64 0,68 0,70 0,80 0,84 Hoppsan! Decimalkomma?
(22 februari 2016 F6.11 ) Klassen SortedMeasurements Kan använda java.util.locale (importeras) i formatsatsen: public void print() { for(int i=0; i<thevalues.size(); i++) { System.out.format(Locale.US, "%6.2f", thevalues.get(i)); if (i%10==9) { System.out.println(); 0.00 0.07 0.13 0.17 0.23 0.28 0.32 0.38 0.43 0.50 0.51 0.54 0.60 0.67 0.70 0.71 0.72 0.82 0.83 0.91 Svensk standard erhålls med System.out.format(new Locale("sv", "SE"), "%6.2f", thevalues.get(i));
(22 februari 2016 F6.12 ) Klassen SortedMeasurements Man kan även redigera texten i en tostring-metod: public String tostring() { String res = ""; for (double x: thevalues) { res = res + String.format(Locale.US, "%6.2f", x); return res; som skulle kunna ge strängen 0.00 0.07 0.13 0.17 0.23 0.28 0.32 0.38 0.43 0.50 0.51 0.54 0 Observera att format här är en klassmetod i klassen String Länk till klassen SortedMeasurements
(22 februari 2016 F6.13 ) Metoden format Metoden format finns både som instansmetod i flera io-klasser (t ex i PrintStream som är vad System.out är och som klassmetod i klassen String. I de första fallet skickas den resulterande strängen till strömmen (filen terminalen,... ). I det andra fallet returneras den resulterande strängen. Den finns i två varianter: och format(formatsträng, v 1, v 2, v 3,...) format(locale, formatsträng, v 1, v 2, v 3,...)
(22 februari 2016 F6.14 ) Metoden format Formatsträngen är i princip det som metoden resulterar i men vissa delar ( formatspecifierarna ) byts ut mor värden av resterande parametrar. Exempel: System.out.format("exp(%2.1f) = %2.4e\n", 10.0, Math.exp(10)); producerar utskriften exp(10,0) = 2.2026e+04 Hm, ska exponentformatet använda decimalpunkt men flyttalsformatet decimalkomma???
(22 februari 2016 F6.15 ) Formatspecifikationer s för strängar. Exempel: %10s, %-20s d för heltalstyper. Exempel: %d, %10d f för flyttalstyper. Exempel: %10.2f, %-15.5f e för flyttalstyper på exponentformat: %-12.4e Det första talet anger fältets bredd. Läggs högerjusterat om värdet tar mindre plats än fältbredden. Negativt anger vänsterjusterat. Siffran efter punkten anger antalet decimaler.
(22 februari 2016 F6.16 ) Jämförelse av strängar Låt s och t vara referenser till två String-objekt. s.equals(t) returnerar true om strängarna är lika långa och innehåller samma tecken false i annat fall Exempel på användning: if (answer.equals("yes")) {... while (!p.getname().equals(q.getname())) {... Använd aldrig operatorn == för att testa om två strängar är lika! DrJava
(22 februari 2016 F6.17 ) Jämförelse av strängar Anropet s.compareto(t) returnerar ett negativt heltal om s kommer före t i alfabetisk ordning, noll om s och t innehåller samma tecken (dvs om s.equals(t) är true) och ett positivt heltal om s kommer efter t i alfabetisk ordning Observera: alfabetisk ordning betyder här i ordning efter ascii-koder (egentligen unikoder)
(22 februari 2016 F6.18 ) Exempelklassen StringList Klassen en underhåller en lista med strängar ( ord ) i bokstavsordning. import java.util.arraylist; import java.util.scanner; import java.io.*; public class StringList { private ArrayList<String> thelist; public StringList() { thelist = new ArrayList<String>();
(22 februari 2016 F6.19 ) Exempelklassen StringList public void add(string str) { int i=0; while( i<thelist.size() && str.compareto(thelist.get(i))>0) { i++; if (i==thelist.size() str.compareto(thelist.get(i))!=0 ) { // If not found thelist.add(i,str); Observera: Varje ord lagras bara en gång Ordningen i såväl while- som if-villkoren
(22 februari 2016 F6.20 ) Exempelklassen StringList /** * Reads a file and add the words to the list */ public void load(string filename) throws IOException { FileInputStream file = new FileInputStream(filename); Scanner fscan = new Scanner(file); while(fscan.hasnext()) { add(fscan.next().tolowercase()); Observera: FileInputStream throws IOException tolowercase()
(22 februari 2016 F6.21 ) Exempelklassen StringList public String tostring() { return thelist.tostring(); public static void main(string[] a) throws IOException { StringList list = new StringList(); list.load("indata.txt"); System.out.println(list); Som ger utskriften [aldrig, av, blir, blott, bryt, bryts, br?det, b?sta, dag, dagen, den, det, dr?mmen, d?r, elden, en, finns, full, f?rd, gryr, gâng, hast, i, man, men, mening, mâl, mâlet, m?dan, m?tta, nattlâng, nog, nya, och, o?ndligt, pâ, rast, som, sover, stora, st?rst, st?llen, sâng, s?mnen, trygg, t?rst, t?nds, upp, vâr, vârt, v?gen, v?rd,?r,?ventyr] Öhhh?
Exempelklassen StringList /** * Reads a file and add the words to the list */ public void load(string filename) throws IOException { FileInputStream instream = new FileInputStream(filename); Scanner fscan = new Scanner(instream, "ISO-8859-1"); while(fscan.hasnext()) { add(fscan.next().tolowercase()); [aldrig, av, blir, blott, bryt, bryts, brödet, bästa, dag, dagen, den, det, drömmen, där, elden, en, finns, full, färd, gryr, gång, hast, i, man, men, mening, mätta, mål, målet, mödan, nattlång, nog, nya, och, oändligt, på, rast, som, sover, stora, ställen, störst, sång, sömnen, trygg, tänds, törst, upp, vägen, värd, vår, vårt, är, äventyr] Länk till klassen StringList (22 februari 2016 F6.22 )
(22 februari 2016 F6.23 ) Metoderna equals och compareto i andra klasser För att jämföra objekt ur en egen klass (säg klassen Dice) så skriver man metoderna boolean equals(dice d) om man vill se om två objekt är lika int compareto(dice d) om man vill kunna ordna objekten i storleksordning Alla inbyggda klasser i Java som behöver jämföra objekt använder just dessa namn. Metoden equals finns alltid (defineras i basklassen Objekt) men den gör knappast vad man vill. (Hur skulle den kunna det?)
(22 februari 2016 F6.24 ) Exempelklasserna Word och WordList Samma problem som i exemplet StringList men vi vill också veta hur många gånger varje ord förekommit. Varje ord måste förses men en frekvensräknare. Gör en till klass: public class Word { private String theword; private int frequency; public Word(String theword) { this.theword = theword; this.frequency = 1; // <<< public String tostring() { return theword + " : " + frequency;
(22 februari 2016 F6.25 ) Exempelklassen Word public void increasefrequency() { frequency++; public String getword() { return theword; public int getfrequency() { return frequency;
(22 februari 2016 F6.26 ) Exempelklassen Word public boolean equals(word w) { return theword.equals(w.theword); public int compareto(word w) { return theword.compareto(w.theword); // End of class Word Länk till klassen Word
(22 februari 2016 F6.27 ) Exempelklassen WordList Klassen WordList blir mycket lik klassen StringList: import java.util.arraylist; import java.util.scanner; import java.io.*; public class WordList { private ArrayList<Word> thelist; //<<< Word instead of String public WordList() { thelist = new ArrayList<Word>();
(22 februari 2016 F6.28 ) Exempelklassen WordList public void add(word word) { //<<< Word instead of String int i=0; while( i<thelist.size() && word.compareto(thelist.get(i))>0) { i++; if (i==thelist.size() word.compareto(thelist.get(i))!=0 ) { thelist.add(i,word); else { thelist.get(i).increasefrequency(); //<<< Count frequency
(22 februari 2016 F6.29 ) Exempelklassen WordList public void load(string filename) throws IOException { FileInputStream file = new FileInputStream(filename); Scanner fscan = new Scanner(file, "ISO-8859-1"); while(fscan.hasnext()) { add(new Word(fscan.next().toLowerCase())); public String tostring() { return thelist.tostring();
Exempelklassen WordList public void print() { for (Word w : thelist) { System.out.format("%12s : %4d\n", w.getword(), w.getfrequency()); Exempel på output: aldrig : 1 av : 2 blir : 1 blott : 1 bryt : 2 bryts : 1 brödet : 1 bästa : 2 dag : 1 dagen : 3 den : 4 det : 3 drömmen : 1 (22 februari 2016 F6.30 )
(22 februari 2016 F6.31 ) Exempelklassen WordList /** * Demonstrates a insertion sort using an arraylist */ public void printfrequencyordered() { ArrayList<Word> fsorted = new ArrayList<Word>(); for (Word w : thelist) { int i=0; while(i<fsorted.size() && w.getfrequency() < fsorted.get(i).getfrequency()) { i++; fsorted.add(i, w); for (Word w : fsorted) { System.out.format("%3d %s\n", w.getfrequency(), w.getword());
Exempelklassen WordList Exempel på utskrift: 6 är 4 den 3 och 3 en 3 det 3 dagen 2 upp 2 i 2 där 2 bästa 2 bryt 2 av 1 äventyr 1 vårt 1 vår 1 värd 1 vägen 1 törst 1 tänds 1 trygg 1 sömnen Länk till klassen WordList (22 februari 2016 F6.32 )
(22 februari 2016 F6.33 ) Ytterligare något om strängar String-objekt är konstanta kan ej förändras. Kan alltså riskfritt delas mellan objekt Klassen StringBuffer kan också användas för att representera stängar men dessa kan ändra både till längd och innehåll. Bra alternativ om långa strängar ska byggas upp i en loop (t ex i tostring-metoder). Det finns en stor mängd metoder för att hantera strängar. Se javadokumentationen!
(22 februari 2016 F6.34 ) Konverteringar från tal till String Några olika sätt: Genom konkatenering med en sträng. Exempel: int x = 12; String s = "" + x; Med hjälp av metoden String.valueOf(x) där x är av någon primitiv datatyp. Med metoden String.format. Exempel: String s = String.format("%5.2f \t %9.6f \t %12d", Math.PI, Math.E, 42);
(22 februari 2016 F6.35 ) Konvertering från String till tal Kan (bl a) göras med hjälp av parsemetoderna i omslagsklasserna. Exempel: double d = Double.parseDouble("2.5"); Kan naturligtvis bli fel Kan också göras med klassen Scanner. Exempel: Scanner sc = new Scanner("13 3.5 12"); sc.uselocale(locale.us); System.out.println(sc.nextInt()); // Skriver 13 System.out.println(sc.nextDouble()); // Skriver 3.5 System.out.println(sc.nextInt()); // Skriver 12 Finns stort antal andra klasser som kan användas för detta ändamål!
(22 februari 2016 F6.36 ) Tips för lektion 9 1. Metoderna next, nextint, nextdouble,... läser förbi s k white space (dvs blanktecken, tabtecken och radbyten) framför ordet (talet) men inte efter ordet (talet). Det innebär att om ett tal läses från en rad så ger nästa nextline slutet på samma rad och inte raden efter det som talet stor på. 2. Följ instruktionerna (som säger spara som) när ni hämtar indatafilen persons.txt. Copy-paste kan ge felaktiga radslut. 3. Filen persons.txt är kodad i ISO-8859-1 (Latin 1). Om ni kör på ett system som inte har det som default måste ni ange det när ni skapar Scanner-objektet.