• No results found

Föreläsning 1-2. Språkkonstruktioner i Java. Introduktion till delar av Javas klassbibliotek

N/A
N/A
Protected

Academic year: 2022

Share "Föreläsning 1-2. Språkkonstruktioner i Java. Introduktion till delar av Javas klassbibliotek"

Copied!
83
0
0

Loading.... (view fulltext now)

Full text

(1)

Föreläsning 1-2

Innehåll

Språkkonstruktioner i Java

Interface Exceptions

Introduktion till generik

Autoboxing - och unboxing

Introduktion till delar av Javas klassbibliotek

Java Collections Framework  interface och klasser för samlingar av element

interfacen Iterator och Iterable och foreach-sats i Java - används för att traversera genom en samling element

Jämföra objekt  metoden equals, interfacet Comparable

(2)

Språkkonstruktioner i Java, Javas klassbibliotek - mål

Undervisningsmoment:

föreläsning 1-2 övning 1

laboration 1 Avsnitt i läroboken:

1.1-1.6, 2.1, Appendix A6, A11, A12 I gamla upplagan: 1.1-1.3, 2.1-2.4, 4.1

Exempel på vad du ska kunna

Förklara begreppen: abstraktion, abstrakt datatyp, specikation, implementation, interface, pre- och post-conditions

deklarera interface i Java

Skriva klasser som implementerar interface

(3)

Språkkonstruktioner i Java, Javas klassbibliotek - mål, forts

Exempel på vad du ska kunna, forts

Skriva metoder som genererar exception

Förklara begreppen: generik, typparameter, autoboxing och unboxing Använda generiska klasser

Implementera generiska klasser

Använda en iterator för att traversera en samling element

Implementera iteratorer för enkla datastrukturer som listor och vektorer

Förklara interfacet Comparable och kunna implementera detta interface

Formulera testfall och använda JUnit för att testa klasser.

Förklara begreppen: skuggning, överlagring, polymorsm

(4)

Objektorienterad design

Man utgår från de data programmet ska arbeta med, alltså de verkliga

saker (objekt) som nns i problemet.

Objekten har

egenskaper (attribut)

operationer som kan utföras på objektet (motsvaras av metoder)

Objekten beskrivs i en klass. Klassen fungerar alltså som mall för objekten.

Vi gör en abstrakt modell av verkligheten. Endast egenskaper som är väsentliga för problemet nns med.

Att abstrahera betyder att bortse från oväsentliga detaljer för att istället framhäva det som är relevant.

(5)

Abstrakt datatyp (ADT)

Denition

En abstrakt modell tillsammans med de operationer man kan utföra på den.

Exempel:

Abstrakt modell: komplexa tal

Operationer på modellen: hämta realdel, hämta imaginärdel, addera . . .

En ADT motsvaras av en specikation av en klass eller av ett interface En klass är en implementering av en ADT

(6)

Abstrakta datatyper

Fördelar

Man får en väldenierad utvidgning av programspråket (ett klassbibliotek).

Utvidgningen gör det enklare för användaren att lösa sitt problem.

implementeringen kan ändras utan att det påverkar resten av programmet.

En ADT kan utnyttjas för era problem (component reuse).

En ADT kan testas separat.

(7)

Interface

Interface i Java

Betyder gränssnitt

Innehåller ingen implementering Alla metoder är implicit publika

Kan användas för att specicera en ADT

public interface ComplexNumber { /** returns real part */

double getRe();

/** returns imaginary part */

double getIm();

/** adds this number and rhs and returns result as a new complex number */

ComplexNumber add(ComplexNumber rhs);

(8)

Interface

Implementera ett interface

Ett interface kan implementeras av en eller era klasser.

public class MyComplexNumber implements ComplexNumber { private double re;

private double im;

public MyComplexNumber(double re, double im) { this.re = re;

this.im = im;

}

public double getRe() { return re;

} ...

(9)

Interface

Implementera ett interface, forts

...

public double getIm() { return im;

}

public ComplexNumber add(ComplexNumber rhs) {

return new MyComplexNumber(re+rhs.getRe(),im+rhs.getIm());

} }

(10)

Interface

Implementera era interface

En klass kan implementera era interface

men bara ärva från en klass.

public class MyComplexNumber2 implements ComplexNumber, Cloneable { // implementering av alla metoder i interfacen

// ComplexNumber och Cloneable }

(11)

Interface

Interface som typnamn

Interface kan användas som typnamn.

ComplexNumber c;

public void p(ComplexNumber c) {...}

Fördel: man binder sig inte till en speciell implementering

c = x; är ok när x är en instans av en klass som implementerar interfacet ComplexNumber

anrop p(x) är ok när x är en instans av en klass som implementerar interfacet ComplexNumber

(12)

Interface

Kontrakt

Interfacet fungerar som kontrakt.

Flera implementeringar (klasser) kan uppfylla kontraktet.

Användare har tillgång till alla operationer i ett interface innan de är implementerade.

Det är bara när man skapar instanser som man behöver tillgång till en implementerande klass.

Man kan enkelt byta en implementerande klass mot en annan.

ComplexNumber c1 = new MyComplexNumber(1,2);

ComplexNumber c2 = c1;

c2 = c2.add(c1);

p(c2);

(13)

Interface

Övning

Övning

Deniera ett interface med namnet Resizable med en metod resize som är void och har en parameter scaleFactor av typen double.

Övning

Ändra i klassen Square så att den implementerar interfacet Resizable.

public class Square { private double side;

public Square(double side) { this.side = side;

}...

(14)

Pre- och postconditions

Kontrakt på metodnivå

Preconditions är villkor som måste vara uppfyllda för att en metod ska kunna utföra sin uppgift.

Ibland nns inga preconditions.

När de nns, är de ofta villkor som parametrarna ska uppfylla.

Postconditions beskriver hur exekvering av metoden förändrar tillståndet hos objektet.

Behöver bara anges om metoden förändrar tillståndet (oftast void-metoder).

För metoder som inte är void bör man i stället ge en kommentar om vad som returneras.

(15)

Pre- och postconditions

Exempel

public class BankAccount { private int balance;

...

/*** Deposits the specified amount.

* pre: The specified amount is >= 0

* post: The specified amount is added to balance

* @param n The amount to deposit public void deposit(int n) {*/

balance = balance + n;

} ...

(16)

Fel i program (buggar)

Olika slags fel

Syntaxfel bryter mot språkets grammatik (syntax).

Exempel: glömt ett {, glömt deklarera en variabel innan den används ...

Exekveringsfel (Runtime errors eller Exceptions) upptäcks vid exekvering.

Exempel: ArrayIndexOutOfBoundException, NullPointerException, ...

Logiska fel Programmet kan köras men ger fel resultat.

(17)

Exekveringsfel

Vad händer vid ett exekveringsfel?

Ett objekt (exception) skapas som beskriver typen av fel.

Programmet avbryts.

Ett felmeddelande skrivs ut där

typ av fel

stacktrace (sekvensen av metodanrop)

framgår.

(18)

Exception

Sammanfattning

Betyder undantag

Exception genereras (throws) vid exekveringsfel.

Man kan fånga (catch) exception och då själv avgöra hur felsituationen ska hanteras.

Man kan skriva kod som genererar exception inuti en metod. (Används om det uppstår en situation som gör det omöjligt för metoden att

utföra sin uppgift.)

(19)

Exception

Olika typer av fel beskrivs av olika subklasser till klassen Exception.

Exception

RuntimeException IOException

FileNotFoundException

...

ArrayIndexOutOfBoundException

NullPointerException

NoSuchElementException

...

(20)

Exceptions

Unchecked och checked

Det nns två slag av Exceptions:

Unchecked Exceptions

Subklass till RuntimeException.

Behöver inte fångas.

Exempel: ArrayIndexOutOfBoundException, NullPointerException

Checked Exceptions

Måste fångas någonstans i anropskedjan, annars kompileringsfel.

Metoder som genererar sådana måste ange det i sin metodrubrik.

Exempel:

public Scanner createScanner(String fileName) throws

FileNotFoundException { } ...

(21)

Exceptions

Unchecked och checked, forts

Unchecked Exceptions  används då felet beror på programmeraren

Ex: NullPointerException eller ArrayIndexOutOfBoundsException

Checked Exceptions  används då felet inte beror på programmeraren

Ex: FileNotFoundException om man försöker öppna en l som inte

nns

(22)

Fånga checked Exceptions

Exempel

När man anropar en metod som genererar en checked exception måste man ta hand om det. Normalt fångar man det i en try-catch-sats:

Scanner scan = null;

try {

// försöker öppna en fil med namnet fileName scan = new Scanner(new File(fileName));

} catch (FileNotFoundException e) {

System.err.println("Couldn't open file " + fileName);

System.exit(1);

}... använd scan ...

Om exception inträar, avbryts exekveringen av satserna i try-blocket och satserna i catch-blocket exekveras.

(23)

Fånga checked Exceptions

Forts

I satsen catch(Exception e) kan t.ex. följande metoder användas för att få mer information:

e.printStackTrace(); som skriver ut information om raden där felet inträat och den/de metodanrop som lett till denna rad.

e.getMessage(); som returnerar en sträng med meddelande om felets art.

Exempel:

Scanner scan = null;

try {

scan = new Scanner(new File(fileName));

} catch (FileNotFoundException e) { e.printStackTrace();

System.exit(1);

}... använd scan ...

(24)

Fånga exception

Mönster

try {

// kod som kan generera exception } catch (ExceptionClass e) {

// kod för att hantera exception }

try {

// kod som kan generera exception } catch (ExceptionClass1 e1) {

// kod för att hantera exception av typen ExceptionClass1 } catch (ExceptionClass2 e2) {

// kod för att hantera exception av typen ExceptionClass2 } finally {

// kod som utförs efter try-blocket eller efter catch-blocket }

(25)

Ignorera checked Exceptions

Man kan ignorera en checked Exception och kasta det vidare till den anropande metoden.

I så fall måste man ange det i metodrubriken i den metod där exception genereras:

public Scanner createScanner(String fileName) throws

FileNotFoundException { // Här genereras exception om filen inte går att öppna Scanner scan = new Scanner(new File(fileName));

return scan;

}

I den metod som anropar createScanner måste man ta hand om detta exception och kan korrigera felet på valfritt sätt.

(26)

Hantera unchecked exceptions

Metod som genererar unchecked exception behöver inte ange det i sin rubrik

Kan anges i kommentar

Den som anropar en metod som kan generera en unchecked exception behöver inte (men kan) fånga den i en try-catch-sats

Leder till exekveringsfel om de inte fångas.

(27)

Generera exception

Exempel:

throw new IllegalArgumentException("amount to deposit < 0");

Mönster:

throw new ExceptionClass();

throw new ExceptionClass(message);

Eekt:

Ett nytt exception-objekt skapas.

Exekveringen av metoden avbryts.

Javasystemet letar efter fångande catch-block.

(28)

Generera exception

Exempel

/*** Deposits the specified amount.

* pre: The specified amount is >= 0

* post: The specified amount is added to balance

* @param n The amount to deposit

* @throws IllegalArgumentException if the specified amount is < 0 public void deposit(int n) {*/

if (n < 0) {

throw new IllegalArgumentException("amount to deposit < 0");

}balance = balance + n;

}

(29)

Egna exceptionklasser

Om man vill kan man implementera en egen exceptionklass (behövs sällan, det nns färdiga exceptionklasser i Javas bibliotek för de esta situationer).

Om den ska vara checked:

public class SpellException extends Exception { } ...

Om den ska vara unchecked:

public class SomeSortOfException extends RuntimeException { } ...

(30)

Exceptions

Övning

Övning

1. Ändra följande metod så att exception genereras i de fall det är lämpligt.

/*** Withdraws the specified amount.

* pre: The specified amount is >= 0 and <= balance

* post: Balance is decreased by the specified amount

* @param n The amount to withdraw public void withdraw(int n) {*/

balance = balance - n;

}

2. Antag att variabeln acc refererar till ett bankkonto-objekt och att

metoden withdraw nns i bankkonto-klassen. Anropa withdraw och skriv

(31)

Autoboxing  unboxing

Primitiva typer - wraperklasser

Primitiva typer i Java:

boolean short intlong charbyte float double

Motsvarande wrapper-klasser:

Boolean Short Integer LongCharacter ByteFloat

Double

(32)

Autoboxing  unboxing

Exempel:

Integer i = new Integer(2);

Fr o m Java 5.0 kan vi skriva:

i = i + 1;

Detta var inte tillåtet i i tidigare versioner av Java. Där måste man skriva:

i = new Integer(i.intValue() + 1);

(33)

Autoboxing  unboxing

Autoboxing automatisk konvertering från primitiv typ till objekt av motsvarande wrapper-klass

Unboxing automatisk konvertering av objekt av wrapperklass till motsvarande primitiva typ

Exempel:

Integer k = 3; // autoboxing int j = k; // unboxing Integer i = new Integer(2);

i = i + 1;

// Unboxing av i för att beräkna i+1.

// Därefter autoboxing av resultatet vid // tilldelningen.

(34)

Autoboxing  unboxing

i samband med collection-klasser

Praktiskt när man vill använda Javas collection-klasser för att lagra element av primitiv typ. Ex:

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

myList.add(1); // Konvertering till Integer-objekt här.

...int j = myList.get(0); // Konvertering till int här.

(35)

Generik

Introduktion till Generik i Java

Här introduceras generiska klasser och interface.

Mer om generik nns att läsa på OH-bilderna Mer om generik som

nns på kursens hemsida:

generik och arv wildcards

vektorer och generik generiska metoder

Vissa av dessa moment dyker upp och förklaras i samband med laborationer.

(36)

Generik

Bakgrund

Klasser bör implementeras så att de blir generella d.v.s. går att använda i många olika sammanhang.

En klass som hanterar en lista av element ska inte skrivas så att den bara kan hantera listor med heltal.

Lösningen har i tidigare javaversioner varit att ge parametrar i metoderna den mest generella typen  Object.

Ex: add-operationen i en lista kunde ha signaturen public boolean add(Object x);

(37)

Generik

Bakgrund forts

Typosäkerhet utan generik!

I den gamla modellen kunde man skriva:

myList.add(new Integer(1));

myList.add(new Integer(2));

myList.add(new Person(Kalle));

Om avsikten är att listan ska innehålla tal, har vi gjort fel på rad 3.

Kompilatorn kan inte upptäcka detta  koden är korrekt, både Integer och Person är subklasser till Object.

(38)

Generik i Java

Ger oss möjlighet att abstrahera över typer

Vi kan använda typparametrar när vi denierar en klass. Ex:

public class ArrayList<E> {...}

Vid användning av en generisk klass anges ett aktuellt typargument.

Ex:

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

(39)

Generik i Java

Kompilatorn kommer att upptäcka typfel. Ex:

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

myList.add(new Person("Kalle"));

ger nu kompileringsfel, myList får enligt sin deklaration endast innehålla objekt av typen Integer.

(40)

Exempel på en generisk klass

java.util.ArrayList

Utdrag ur den generiska klassen java.util.ArrayList:

public class ArrayList<E> { public ArrayList() {...}

public boolean add(E x) {...}

public void add(int index, E x) {...}

public E get(int index) {...}

} ...

Alla add-metoder har inparameter av typen E. Därför kan enbart objekt av klassen E (eller subklasser till denna) sättas in i listan.

(41)

Exempel på en generisk klass

java.util.ArrayList, forts

Observera att inte alla operationer i ArrayList<E> har E som

typparameter. T.ex. har contains och remove följande signaturer:

public boolean contains(Object x);

public boolean remove(Object x);

Användare som inte känner till den exakta typen av ett element x ska

kunna anropa metoderna. Dock kommer man att få resultat true om och endast om x nns i listan (och alltså även är av rätt typ).

(42)

Användning av en generisk klass

java.util.ArrayList

Exempel:

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

list.add("Lisa");

list.add("Per");

...String s = list.get(0);

System.out.println(s);

...

(43)

Implementering av generisk klass

Java 1.4

public class Container { private Object item;

public Container(Object x) { item = x;

}

public Object get() { return item;

}

public void set(Object x) { item = x;

} }

Fr o m Java 5.0 generisk klass

public class Container<E> { private E item;

public Container(E x) { item = x;

}

public E getItem() { return item;

}

public void setItem(E x) { item = x;

} }

(44)

Generisk klass med era typparametrar

Implementering

public class Pair<K, V> { private K key;

private V value;

public Pair(K key, V value) { this.key = key;

this.value = value;

}

public V getValue() { return value;

}

public void setValue(V val) { value = val;

}

(45)

Generisk klass med era typparametrar

Användning

Exempel:

Pair<String, Integer> pair = new Pair<String, Integer>("June", 30);

int nbrDays = pair.getValue();

(46)

Generiska interface

Även interface kan vara generiska. Ex:

public interface Set<E> { boolean add(E x);

int size();

boolean contains(Object x);

} ...

(47)

Generik  syntax

Deklaration av parametriserade (generiska) klasser/interface:

public class Set<E> {...}

public interface Comparable<T> ...

public class Pair<K,V> ...

Klassen/interfacet har en parameterlista som omges av tecknen < och

>.

En parameter namnges med en typvariabel (markeras ovan) som kan vara en godtycklig identierare.

Om det är era parametrar används komma som skiljetecken.

(48)

Generik  syntax

Generiska klasser/interface denierar en samling av typer: en typ för varje möjlig instansiering av typparametrarna.

Deklarationen av Set<E> på föregående bild denierar t ex följande parametriserade typer:

Set<Integer>

Set<Character>

Set<String>

Set<Set<String>> // nästling tillåten ...

(49)

Generik  syntax

Vi kan använda parametriserade typer i deklaration av attribut, variabler, metodparametrar, ... Ex:

ArrayList<Integer> myList;

Pair<Integer, String> aPair;

public static printSet(Set<Integer> s) {...}

När vi skapar instanser av generiska klasser anges typargumenten inom tecknen < och > Ex:

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

Pair<Integer, String> aPair =

new Pair<Integer, String>();

(50)

Generik  syntax

I generiska klasser/interface kan typparametrarna användas för att deklarera attribut, variabler, ... Ex:

public class Container<E> { private E item;

public Container(E x){

this.item = x;

}

public E getItem()){

returnh item;

...} }

(51)

Restriktioner för typparametrar och typvariabler

Parameter till generisk klass kan inte vara primitiv typ:

SomeClass<int> c = ... // Går inte!

Typvariabler kan inte användas för att skapa objekt:

public class SomeClass<E> { public void p() {

E x = new E(); // Fel!

...

Typparametrar kan inte användas för att överlagra metoder:

public class MyClass<T,U> { public void p(T x) {...}

public void p(U x) {...} // Fel!

...

(52)

Introduktion till delar av Javas klassbibliotek

Java Collections Framework  interface och klasser för samlingar av element

interfacen Iterator och Iterable och foreach-sats i Java - används för att traversera genom en samling element

interfacet Comparable

Läsanvisningar

Interfacet List och Klassen ArrayList behandlas i avsnitt 2.1.

Fler interface och klasser behandlas senare i kursen/läroboken.

Dokumentation

På Javas hemsida (länk nns på kursens hemsida) nns dokumentation av Javas standardklasser.

(53)

JCF  Java Collections Framework

Är en hierarki av interface, abstrakta klasser och konkreta klasser för samlingar av element.

Finns i paketet java.util.

Basen i hierarkin är ett interface Collection:

interface Collection<E> { boolean add(E x);

boolean contains(Object x);

boolean remove(Object x);

boolean isEmpty();

int size();

} ...

(54)

JCF  interface hierarki

<<Interface>>

Map

<<Interface>>

SortedMap

<<Interface>>

Collection

<<Interface>>

Queue

<<Interface>>

List

<<Interface>>

Set

<<Interface>>

SortedSet

(55)

JCF  interface hierarki

Collection en samling av element, där dubbletter tillåts Queue en samling av element som utgör en kö

List en samling element där dubbletter tillåts och där

positionering är möjlig (första, sista, element på plats i, ...) Set en samling element där dubbletter är förbjudna

SortedSet som Set men med krav att elementen går att jämföra

Map en samling av element, där varje element har en en nyckel och ett värde (jfr. lexikon)

SortedMap som Map men med krav att nycklarna går att jämföra

(56)

JCF  några klasser

Interface Implementering

Queue LinkedList, PriorityQueue List ArrayList, LinkedList

Set HashSet

SortedSet TreeSet

Map HahsMap

SortedMap TreeMap

(57)

Iteratorer

Antag att vi lagrar ett antal personer i en lista (eller i någon annan samlingsklass):

ArrayList<Person> pList = new ArrayList<Person>();

// här sätts Person-objekt in i samligen }

Hur ska vi göra för iterera genom samligen och behandla alla personerna (t.ex. skriva ut alla personernas namn)?

(58)

Interfacet Iterator<E>

En instans av en klass som implementerar interfacet Iterator används för att iterera över alla element i en samling.

public interface Iterator<E> {

/** Returns true if the iteration has more elements. */

boolean hasNext();

/** Returns the next element in the iteration. */

E next();

/** Removes from the underlying collection the last element returned by the iterator (optional). */

void remove();

}

Hur får man tag på ett iterator-objekt?

(59)

Interfacet Iterable<E>

I Java nns följande interface:

public interface Iterable<E> {

/** Returns an iterator over a set of elements of type E */

Iterator<E> iterator();

}

Interfacet Collection ärver interfacet Iterable:

public interface Collection<E> extends Iterable<E> ...

Alla klasser som implementerar Collection måste alltså implementera metoden iterator().

(60)

JCF  interface hierarki

med Iterable<E> och Iterator<E>

<<Interface>>

Collection

<<Interface>>

Queue

<<Interface>>

List

<<Interface>>

Set

<<Interface>>

SortedSet

<<Interface>>

Iterable iterator()

<<Interface>>

Iterator hasNext()

next() remove()

<<Interface>>

Map

<<Interface>>

SortedMap

(61)

Användning av iterator

Exempel

ArrayList<Person> pList = new ArrayList<Person>();

// här sätts Person-objekt in i samlingen ...Iterator<Person> itr = pList.iterator();

while (itr.hasNext()) { Person p = itr.next();

// behandla p } ...

Lägg märke till hur man skaar sig en iterator  genom att anropa metoden iterator.

(62)

Metoden iterator()

Exempel på collection-klass med metoden iterator

public class ArrayCollection<E> implements Collection<E> { private E[] theCollection;

private int size;

... impl av konstruktor, add, ...

public Iterator<E> iterator() { return new ArrayIterator();

}

private class ArrayIterator implements Iterator<E> { .... implementering på nästa bild ...

} }

(63)

Implementering av interfacet Iterator<E>

Exempel: Klassen ArrayIterator

private class ArrayIterator implements Iterator<E> { private int pos;

private ArrayIterator() { pos = 0;

}

public boolean hasNext() { return pos < size;

} ...

(64)

Implementering av interfacet Iterator<E>

Exempel: Klassen ArrayIterator, forts

...

public E next() { if (hasNext()) {

E item = theCollection[pos];

pos++;

return item;

} else {

throw new NoSuchElementException();

} }

public void remove() {

throw new UnsupportedOperationException();

} }

(65)

Implementering av interfacet Iterator<E>

Inre klass

Den klass som implementerar interfacet Iterator kan vara inre klass i den klass som representerar samlingen.

En inre klass har tillgång till alla attribut i den omgivande klassen  det utnyttjas t.ex. i operationen next.

Den kan vara privat, och ha en en privat konstruktor, eftersom det bara är den omgivande klassen som skapar instanser. Metoderna hasNext, ... måste däremot vara publika eftersom interfacet

Iterator föreskriver detta.

(66)

Implementering av interfacet Iterator<E>

Kommentar

Implementeringen som visats här är förenklad:

Iteratorer har enligt sitt kontrakt inte till uppgift att klara av att samlingen modieras mellan anrop av next().

En korrekt iterator-implementering måste upptäcka detta och generera en exception om samlingen modieras.

(67)

foreach-sats i Java

Exempel

ArrayList<Person> pList = new ArrayList<Person>();

// här sätts Person-objekt in samlingen ...for (Person p : pList) {

// behandla p }

Ett sätt att enkelt iterera över samlingar. Man slipper att explicit använda en iterator.

for (Person p : pList) ... kan läsas som för varje p i pList. Kan användas för objekt av klasser som implementerar Iterable och för vektorer.

(68)

foreach-sats

Vektorer

Kan också användas för att iterera över elementen i en vektor.

Ex: En metod som skriver ut namn på personer som lagrats i en vektor av typ Person[]:

public void print(Person[] a) { for (Person p : a) {

System.out.println(p.getName());

} }

(69)

Iterator  foreach-sats

Övning

Övning

Antag att vi har följande lista:

LinkedList<Integer> list = new LinkedList<Integer>();

list.add(25);

list.add(42);

...

Summera talen i list genom att använda iterator() resp. foreach-sats.

(70)

foreach-sats

Begränsningar

Foreach-sats kan inte användas när man explicit behöver tillgång till iteratorn i koden.

Exempel: Tag bort alla personer som matchar x ur en ArrayList<Person>

pList:

Iterator<Person> itr = pList.iterator();

while (itr.hasNext()) {

if (itr.next().equals(x)) { itr.remove();

} }

Här behövs iteratorn för att kunna ta bort element.

(71)

foreach-sats

Begränsningar

Foreach-sats kan inte användas för att iterera parallellt över era samlingar, motsvarande följande kod:

ArrayList<Person> list1, list2;

...Iterator<Person> itr1 = list1.iterator();

Iterator<Person> itr2 = list2.iterator();

while(itr1.hasNext() && itr2.hasNext()) {

System.out.println(itr1.next() + " " + itr2.next());

}

(72)

Nästlad foreach-sats

Däremot går det bra med nästlade loopar.

Ex: Skriv ut alla kombinationer av strängar str1 str2 där str1 nns i vektorn first och str2 nns i vektorn second. first och second är av typen String[] :

for (String f : first ) {

for (String s : second) {

System.out.println(f + " " + s);

} }

(73)

Söka efter objekt i en lista

Följande klass beskriver en person:

public class Person {

private String name;

private int idNbr;

public Person (String name, int idNbr) { this.name = name;

this.idNbr = idNbr;

} }

Vad skrivs ut när följande rader exekveras?

ArrayList<Person> list = new ArrayList<Person>();

list.add(new Person("Kalle", 1));

list.add(new Person("Kajsa", 2));

(74)

Jämföra likhet

Metoden equals

Metoden equals används för att jämföra om två objekt är lika:

Person p1 = ...;

Person p2 = ;...

if (p1.equals(p2)) {...}

Metoden equals nns i superklassen Object. Den returnerar true om och endast om de jämförda objekten är identiska.

Om man istället vill att innehållet inuti objekten ska jämföras måste man omdeniera (skugga) equals.

Exempel: Om man vill att två personer ska anses lika när de har samma id-nummer måste man omdeniera equals i klassen Person.

(75)

Omdeniera equals

Specikation

public boolean equals(Object obj);

Ur equals specikation:

x.equals(x) ska returnera true (reexivitet).

Om x.equals(y) returnerar true så ska y.equals(x) returnera true (symmetri).

Om x.equals(y) returnerar true och y.equals(z) returnerar true så ska x.equals(z) returnera true (transitivitet).

x.equals(null) ska returnera false.

(76)

Omdeniera equals  med instanceof

public boolean equals(Object obj) { if (obj instanceof Person) {

return idNbr == ((Person) obj).idNbr;

} else {

return false;

} }

Observera att parametern till equals måste vara av typ Object,

annars blir det inte skuggning. Därför måste också typomvandling till Person ske när man ska använda obj:s idNbr.

Uttrycket obj instanceof Person returnerar true om obj:s typ är Person eller någon subklass till Person.

Uttrycket obj instanceof Person returnerar false om obj har

(77)

Omdeniera (skugga) equals  med instanceof

Fördelar och nackdelar

Uttrycket obj instanceof Person returnerar true om obj:s typ är Person eller någon subklass till Person.

Lösningen tillåter alltså att subklasser ärver equals-metoden.

Man kan använda equals i en arvshieariki och jämföra

subklassobjekt och superklassobjekt.

Kan leda till att equals inte uppfyller kraven i specikationen (om man t.e.x skuggar equals i subklassen).

Detta undviks om man bara tillåter jämförelser mellan objekt av samma typ. Se nästa bild.

(78)

Omdeniera equals  med getClass

public boolean equals(Object obj) { if (obj == this) {

return true;

}if (obj == null) { return false;

}if (this.getClass() != obj.getClass()) { return false;

}return idNbr == ((Person) obj).idNbr;

}

Metoden getClass returnerar typen för det objekt obj refererar till under exekveringen.

(79)

Interfacet Comparable

Specikation

I Java nns ett generiskt interface, Comparable<T>:

public interface Comparable<T> {

/*** Compares this object with the specified object for order.

* Returns a negative integer, zero, or a positive integer as

* this object is less than, equal to, or greater than the

* specified object.

public int compareTo(T x);*/

}

Objekt av klasser som implementerar detta interface går att jämföra med varandra och kan t.ex. sorteras.

(80)

Implementering av interfacet Comparable

Exempel

public class Person implements Comparable<Person> { private String name;

private int idNbr;

...

public int compareTo(Person x) { return idNbr - x.idNbr;

}

public boolean equals(Object obj) { if (obj instanceof Person) {

return compareTo((Person) obj) == 0;

} else {

return false;

} }

(81)

Jämföra likhet

Metoderna compareTo och equals

Interfacet Comparable innehåller bara metoden compareTo.

Men för klasser som implementerar interfacet Comparable nns det två sätt att jämföra avseende likhet:

Person p1 = ...;

Person p2 = ;...

if (p1.compareTo(p2) == 0) {...}

if (p1.equals(p2)) {...}

Båda sätten att jämföra ska ge konsistenta resultat.

Därför bör metoden equals omdenieras i klasser som implementerar Comparable.

(82)

Implementering av interfacet Comparable

Övning

Övning

Ändra klassen Person så att den implementerar interfacet Comparable.

Jämförelsen av Person-objekt ska göras med avseende på namnet.

public class Person { private String name;

private int idNbr;

} ...

(83)

Typparametrar med begränsningar

Ibland behöver man ange begränsning på typparmetern:

public class ASortedCollection<E extends Comparable<E>>

<E extends T> betyder:

E måste vara subklass till T om T är en klass. Det är också tillåtet att E

= T.E måste implementera interfacet T om T är ett interface.

I exemplet ovan anger vi alltså att E måste vara en typ som

implementerar interfacet Comparable<E>. Vi kan därmed använda metoden compareTo på objekt av typen E i implementeringen av ASortedCollection.

References

Related documents

[r]

Kommunen har valt att inte avge yttrande över remissen.. Hälsningar Kristian Egstedt

[r]

8 8:;?@ABCD?ECFGHADAEIJKHLFGHAIHMNAOJIGHPALEKEQJPAOJACJMRSPATLEKMUPJPAVDQHWJGHALEKEQDXA

[r]

[r]

The aim of the work is to point out the possibilities of adapting the teaching process according to individual needs of pupils in a mixed-ability class and to propose strategies

Detta kan vi då i nästa led problematisera utifrån dilemmaperspektivet som vi då baserar på dessa utbildningsmässiga problem som enligt Nilholm (2020) inte går att