Föreläsning 10 OM DELMÅLSKONTROLLEN ; VARIABLERS SYNLIGHET STRING OCH STRINGBUILDER
Denna vecka Läsperiodens sista föreläsning Uppsamlingslabb (laboration 6 redovisas först nästa läsperiod) Ingen resurstid Din ordinarie tenta är i juni inte mars! Delmålskontroll på fredag Laboration 1 5, övning 1 4, föreläsning 1 8 (dvs inte vektorer eller strängar) Vi börjar 14:00 (..)
Delmålskontroll på fredag OBS! Den del av salen du sitter i kommer ha en egen övningsledare och du måste stanna i den salsdelen under alla momenten nedan. Tre delar 1. Du löser skrivningen individuellt. Är du klar innan sluttiden får du lämna in och ta fram en bok, din telefon, eller liknande. Du får även gå ut en sväng om du vill men var tyst så du inte stör de övriga skrivande. 2. Ni sätter er parvis och får ut rättningsmallen som ni läser igenom. Efter ca 10 minuter får ni ut två andra personers skrivningar, som ni rättar enligt anvisningarna i rättningsmallen. När rättningstiden är slut samlar vi in alla de rättade skrivningarna. 3. Du får hämta din egen skrivning och titta på rättningen. Är du nöjd med rättningen lämnar du bara tillbaka skrivningen till din övningsledare igen. Är du inte nöjd med rättningen lämnar du skrivningen till Patrik istället! Ta med snabbreferens penna att skriva med penna i avvikande färg (att rätta med)
Sparta (skrivningslokalen) In genom entrén (utanför ICA Tuna) Direkt till vänster, genom en kort korridor Passerkort krävs (kanske)
Piffa till din sköldpadda: använd klassen Sprite /** Skapar en ikon från en bild, läst från filen med namn file, och av angiven bredd och höjd. */ Sprite(String file, int width, int height); /* Roterar spriten till ett absolut vinkelvärde (grader) */ void setdirection(double deg); /* Flyttar bilden så mitten hamnar i positionen (x,y) */ void movemidto(int x, int y); I Lab05 (Turtle-projektet) finns en bildfil som kan användas: Sprite s = new Sprite(../Lab05/resources/turtle.png, 30, 30); För att figuren ska synas måste den stoppas in i fönstret (här kallat w): w.addsprite(s);
Variablers synlighet
Att deklarera och att använda variabler När vi deklarerar en variabel, t ex int x; inför vi en ny variabel med ett namn och en typ. När namnet används någon annanstans i programmet, t ex x = 5; System.out.println(x); slår kompilatorn upp rätt variabel. Denna uppslagning följer vissa regler synlighetsregler.
Synlighetsregler (1) En parameter är synlig i den metod där den deklarerats. public class BankAccount { public void deposit(double depositamount){ amount += depositamount; printamount(); public void printamount(){ System.out.println( The amount is + amount);
Synlighetsregler (2) En lokal variabel är synlig från den punkt den deklarerats till blockets { slut. public void calculation(){ int x = 32; if(x > 0){ int y = x*10; System.out.println(x);
Synlighetsregler (3) En lokal variabel som deklarerats i en for-sats är endast giltig inom for-satsen. for(int i = 10; i >= 0; i -= 2){ System.out.println( Now the counter is + i); System.out.println( Now the counter is + i); // FEL Den sista raden ger ett kompileringsfel: i cannot be resolved to a variable
Synlighetsregler (4) Attribut och metoder är synliga inom klassen. public class BankAccount{ private double amount; public void deposit(double depositamount){ amount += depositamount; printamount(); public void printamount(){ System.out.println( The amount is + amount);
public class Scopes { private int a; public Scopes(int a) { this.a = a; System.out.println(a); public void p1() { double a = 5.3; System.out.println(a); public void p2() { if (6 * 7 == 42) { boolean a = true; System.out.println(a); public void p3() { { a = 9; System.out.println(a); public static void main(string[] args) { Scopes s = new Scopes(29); s.p1(); s.p2(); s.p3(); Varje gång namnet a används söker kompilatorn upp motsvarande deklaration. Börja leta bland föregående satser i det block { där namnet används Sök därefter utåt, från blocket, via metoden, till klassen Den närmsta deklarationen (enligt denna ordning) används Alltså: En deklaration är giltig i det block { där den står En deklaration kan skuggas av en annan (närmare) Parametrar är giltiga i metoden Programmet skriver ut fyra värden. Vilka?
String & StringBuilder
Klassen String Klassen String beskriver en teckensträng (en följd av tecken). Exempel: String s = "En massa tecken" String empty = ""; s empty en massa tecken
Slå ihop (konkatenera) strängar String s1 = "En text"; String s2 = "En text till"; String result = s1 + " och " + s2; s1 s2 En text result En text till En text och En text till
Längden på en sträng Längden på en sträng kan man få veta genom att anropa metoden length() Exempel: String s1 = "Hej"; String s2 = "4%&6"; String s3 = ""; System.out.println(s1.length()); System.out.println(s2.length()); System.out.println(s3.length());
Notera att Strängen i sig är alltid ett objekt. Man kan alltså anropa en metod direkt på ett strängvärde. Följande: "Hej".length();..är alltså möjligt, och är samma sak som new String("Hej").length(); Man skriver nästan aldrig så. (Den andra konstruktionen är faktiskt möjlig för alla slags objekt, om man inte behöver en referensvariabel till dem.)
Pseudokod: behandla alla tecken i strängen String s =...; for (int i = 0; i < s.length(); i++) { // aktuellt tecken nås med // anropet s.charat(i);
Kod: Behandla alla tecken i strängen Exempel: Räkna antal blanktecken i strängen s. String s = "fem myror är fler än fyra elefanter"; int spaces = 0; for (int i = 0; i < s.length(); i++) { if (s.charat(i) == ' ') { spaces++;
Viktiga operationer på String (urval) /** Skapar en tom sträng("") */ String(); /** Ger antalet tecken */ int length(); /** Ger tecknet som ligger på plats pos */ char charat(int pos); /** true om innehållet i aktuell sträng är lika med innehållet i s */ boolean equals(object s); /** jämför aktuell sträng med s */ int compareto(string s); /* index för den första förekomsten av ch, -1 om ch inte finns */ int indexof(char ch); /** ny sträng med tecknen med index [start, end) */ String substring(int start, int end);
Vad jämförs egentligen här? String s1, s2;... if (s1 == s2) { System.out.println("Samma objekt"); else { System.out.println("Inte samma objekt"); Här jämförs innehållet i referensvariablerna s1 och s2. Vi kontrollerar alltså om s1 och s2 refererar till samma objekt eller inte. s1 s2 abc abc
Jämföra teckensträngar med equals Vill man jämföra innehållet i teckensträngarna måste man använda equals. Från specifikationen: /** Returnerar true om innehållet i aktuell sträng är lika med innehållet i s. */ boolean equals(object s); Exempel: if (s1.equals(s2)) { System.out.println("Samma innehåll"); else { System.out.println("Inte samma innehåll");
Jämföra teckensträngar med compareto (bokstavsordning) /** Jämför aktuell sträng med s. Returnerar 0 om teckensträngarna är lika, ett negativt tal om aktuell sträng är mindre än s, ett positivt tal om aktuell sträng är större än s.*/ int compareto(string s); Exempel: String s1 = "java"; s1.compareto("java") kommer ge ett svar == 0 s1.compareto("javac") kommer ge ett svar < 0 s1.compareto("java") kommer ge ett svar > 0 s1.compareto("jazz") kommer ge ett svar < 0
Klassen StringBuilder Klassen StringBuilder beskriver en följd av tecken som kan läsas av och ändras. Exempel: StringBuilder b = new StringBuilder("En massa tecken"); b.append('!'); b En massa tecken!
Varför StringBuilder? Man kan skapa strängar stegvis med String, men det är inte alltid effektivt. Här skapas en ny sträng (ett nytt objekt) i varje tilldelning. Ibland är det ineffektivt att skapa nya objekt på detta sätt. (Det gör ingen skillnad om man använder +=.) public static String fib(int n) { int f0 = 0; int f1 = 1; int f2 = 1; String result = "1"; for (int i = 2; i <= n; i++) { f2 = f1 + f0; f0 = f1; f1 = f2; result = result + " " + f2; return result;
String vs. StringBuilder Vid mer omfattande manipulationer av strängar rekommenderas StringBuilder. StringBuilder gör att man dynamiskt och effektivt kan ändra i en och samma sträng. Typiskt används metoderna append och insert. Så länge man hanterar konstanta (oföränderliga) strängar är String både enklare och effektivare.
Viktiga operationer på StringBuilder Skapa, ta reda på längd och tecken (som String): /** Skapar en tom strängbuffert */ StringBuilder(); /** Skapa en strängbuffert innehållande en kopia av s */ StringBuilder(String s); /** Returnerar antalet tecken i bufferten */ int length(); /** Returnerar tecknet på plats pos */ char charat(int pos); Skapa String-objekt med samma innehåll: /** skapar ett String-objekt med samma innehåll som denna strängbuffert */ String tostring();
Ändra innehållet i StringBuilder-objekt /* ändrar tecknet på plats k till ch */ void setcharat(int k, char ch); /* lägger till s efter tecknen */ StringBuilder append(string s); /* lägger in s på plats k, flyttar tecknen efter */ StringBuilder insert(int k, String s); /* tar bort tecknet på plats k */ StringBuilder deletecharat(int k); Man kan sätta in värden av andra typer än String i ett StringBuilder-objekt. Det finns flera metoder append och insert. Dessa har en parameter av typen int, double, char,...!
Tidigare exempel, nu med StringBuilder public static String fib(int n) { int f0 = 0; int f1 = 1; int f2 = 1; StringBuilder result = new StringBuilder("1"); for (int i = 2; i <= n; i++) { f2 = f1 + f0; f0 = f1; f1 = f2; result.append( ); result.append(f2); return result.tostring();
Exempel: StringBuilder Vad händer här? String s =...;... StringBuilder b = new StringBuilder(s); int i = 0; while (i < b.length() - 1) { if (b.charat(i) ==. b.charat(i) ==, ) { b.insert(i + 1, ); i++; i++; s = b.tostring();
Metoden tostring Det är vanligt att man lägger till metoden tostring i sina klasser. Metoden tostring anropas automatiskt inuti println och används av debuggern. Den kan alltså användas för att presentera objektet på ett läsligt sätt. tostring deklareras såhär: public String tostring() och används så här: System.out.println(obj.toString()); System.out.println(obj); // betyder samma sak
Metoden tostring Metoden tostring i klassen Point (kap. 3) skulle kunna se ut så här: public String tostring() { return x + " " + y; // (1) eller så här: public String tostring() { StringBuilder b = new StringBuilder(); b.append(x); b.append(' '); b.append(y); return b.tostring(); I enskilda stränguttryck (som (1) ovan) görs automatiskt strängkonkatenering med hjälp av StringBuilder. Dessa två exempel är alltså ekvivalenta.
Lunds Tekniska Högskola Xxxxxxxxxxxxxxxx Xxxxxxxxxxxxxx ÅÅÅÅ-MM-DD