Itereragenomensamlingelement autoboxing-ochunboxing ......Föreläsning2 Innehåll...

Post on 27-Mar-2021

1 views 0 download

Transcript of Itereragenomensamlingelement autoboxing-ochunboxing ......Föreläsning2 Innehåll...

Föreläsning 2Innehåll

Abstrakta datatyper - lista, stack, FIFO-kö, mängd, map, prioritetsköJava Collections Framework (interface och klasser för samlingar avelement)Generiska klasserautoboxing - och unboxingIterera genom en samling element

Datavetenskap (LTH) Föreläsning 2 VT 2020 1 / 55

Abstraktion

I datavetenskap innebär abstraktion att man döljer detaljer på en lägrenivå.Exempel: När vi använder klassen String behöver vi inte veta exakthur tecknen lagras. Det räcker att vi vet vilka metoder vi kan utförapå ett String-objekt.Man har kapslat in (gömt undan) data och koden för metoderna inutiklassen String. Detta kallas inkapsling och är en viktig princip inomobjektorinterad programmering.

Datavetenskap (LTH) Föreläsning 2 VT 2020 2 / 55

Abstrakt datatyp (ADT)

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

Exempel 1:Abstrakt modell: heltalOperationer: +, -, *, . . .

Exempel 2:Abstrakt modell: Klassen String i JavaOperationer: ta reda antal tecken – length()

ta reda på tecknet på plats i – char charAt(int i). . .

Datavetenskap (LTH) Föreläsning 2 VT 2020 3 / 55

Abstrakt datatyp (ADT)Forts.

Exempel 3: En köAbstrakt modell: KöOperationer: sätt in ett element sist i kön

hämta första elementet från könta reda på antal element. . .

Som vi ser sker inkapslingen på olika nivåer och en abstrakt datatypkan vara allt från begreppet heltal som implementeras av den primitivadatatypen int till ett abstrakt begrepp som kö.En abstrakt datatyp är alltså en teoretisk entitet som kanimplementeras av t.ex. en datatyp, en datastruktur eller som i Java aven klass.En abstrakt datatyp har ett gränssnitt (en beskrivning avoperationerna). I Java kan en klass beskrivas av en specifikation ellerett interface.

Datavetenskap (LTH) Föreläsning 2 VT 2020 4 / 55

Abstrakt datatyper för samlingar

I kursen kommer vi att träffa på ett antal abstrakta datatyper som kö,mängd, lista etc.

Vitsen med att använda dessa abstrakta datatyper är att vi kankommunicera oberoende av programspråk och implementering. Närman hör begreppet kö förväntar man sig att den ska ha operationer föratt sätta in sist i kön och ta ut först. Om någon säger mängd vet manatt det är en samling unika element där dubbletter är förbjudna.Skilj på abstrakt datatyp och implementering; Den abstraktadatatypen kö kan implementeras med datastrukturen vektor. Endatastruktur är en konkret representation av data.

Datavetenskap (LTH) Föreläsning 2 VT 2020 5 / 55

Viktiga abstrakta datatyper

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

Stack en följd av element där borttagning av ett element avser detelement som senast satts in.

FIFO-kö en följd av element där insättning gör sist och borttagningförst i kön.

Prioritetskö en kö där borttagning av element avser det viktigaste(minsta) elementet.

Mängd (eng. Set) en samling element där dubbletter är förbjudna.Map en samling av nyckel-värde-par (jfr. lexikon)

Datavetenskap (LTH) Föreläsning 2 VT 2020 6 / 55

Abstrakt datatypen lista

1:a elementet 2:a elementet 3:e elementet 4:e elementet

Abstrakt modell: listaOperationer på modellen:

Lägga in element i listan (först, sist ...)Ta bort ett element ur listanUndersöka om ett visst element finns i listanTa reda på ett elementet i listan (första, sista ...)Undersöka om listan tom...

Datavetenskap (LTH) Föreläsning 2 VT 2020 7 / 55

Abstrakta modelllista

Abstrakt modell

Verkliga problem

Bokregister

Lista

Schema

Inköpslista

Datavetenskap (LTH) Föreläsning 2 VT 2020 8 / 55

Stack

DefinitionEn stack är en följd av element där borttagning av ett element alltid avserdet senast insatta elementet.

Kallas även LIFO-lista, Last In First OutOperationer sker på toppen av stacken.

push pop

Datavetenskap (LTH) Föreläsning 2 VT 2020 9 / 55

Köer

I en FiFO-kö görs insättning sist i följden och borttagning avser första(äldsta) elementet.

First In First Out

offerpoll

I en prioritetskö avser borttagning alltid det mest prioriterade (minsta)elementet.

Det viktigaste först.

Datavetenskap (LTH) Föreläsning 2 VT 2020 10 / 55

Mängd

DefinitionEn mängd (eng. Set) är en en samling element där dubbletter är förbjudna.

Operationer:sätta in ett elementta bort ett elementundersöka om ett element finns i mängden

Datavetenskap (LTH) Föreläsning 2 VT 2020 11 / 55

Map

I en map lagras nyckel-värde-par.

Kan också kallas lexikon eller nyckel-värdetabellNycklarna är unika.Man använder nyckeln för att söka tillhörande värde.Exempel:

nyckel är månad, värde är antal dagar i månaden.nyckel är personnummer, värde är Person-objekt med namn, adress ...

marsaprilmaj...

...313031...

...

nycklar (unika) värden (dubbletter ok)

Datavetenskap (LTH) Föreläsning 2 VT 2020 12 / 55

Diskutera

Välj den abstrakta datatyp (lista, stack, kö, prioritetskö, mängd, map) sompassar bäst för att lösa respektive problem:

Givet en samling element, tag reda på antal unika element.Hålla reda på ett antal arbetsuppgifter som ska utföras. Denarbetsuppgift som tar kortast tid ska utföras först.Räkna antal förekomster av ord i en text.Kontrollera att parenteser är korrekt nästlade – { () () } är ok, { (} )är inte ok.Sortera element.

Datavetenskap (LTH) Föreläsning 2 VT 2020 13 / 55

Abstrakta datatyper i kursen

I kursen kommer du att använda de olika abstrakta datatyperna för att lösaproblem.

Då måste du veta vad som utmärker de olika abstrakta datatypernaoch vad man ska ha dem till.Du kommer att använda färdiga klasser från Javas klassbibliotek somimplementerar dessa abstrakta datatyper.Men du kommer också att få se ”under huven” hur de kanimplementeras.

Datavetenskap (LTH) Föreläsning 2 VT 2020 14 / 55

Java Collections Framework

Är en hierarki av interface, abstrakta klasser och konkreta klasser församlingar av element.Dokumentation av Javas standardklasser och interface finns på Javaswebbsida. Där finns även tuturials, bl.a. om Javas Collection-klasser.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();...

}

Datavetenskap (LTH) Föreläsning 2 VT 2020 15 / 55

Java Collections Framework – interface hierarki

<<Interface>>Map

<<Interface>>SortedMap

<<Interface>>Collection

<<Interface>>Queue

<<Interface>>List

<<Interface>>Set

<<Interface>>SortedSet

<<Interface>>Deque

Datavetenskap (LTH) Föreläsning 2 VT 2020 16 / 55

Java Collections Framework – interface hierarki

Collection en samling av element, där dubbletter tillåtsList en samling element där positionering är möjlig (första, sista,

element på plats i, ...)Queue en samling av element som utgör en köDeque som Queue men man kan sätta in och ta ut element både i

början och i slutet av könSet 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 nyckel-värde-par (jfr. lexikon)SortedMap som Map men med krav att nycklarna går att jämföra

Datavetenskap (LTH) Föreläsning 2 VT 2020 17 / 55

Java Collections Framework – några klasser

Interface KlassQueue ArrayDeque, LinkedList, PriorityQueueDeque ArrayDeque, LinkedListList ArrayList, LinkedListSet HashSetSortedSet TreeSetMap HashMapSortedMap TreeMap

Datavetenskap (LTH) Föreläsning 2 VT 2020 18 / 55

Generiska klasser

Javas samlingsklasser är generiska.

En generisk klass har en eller flera typparametrar. Ex:

public class ArrayList<E> {...}

Vid användning av en generisk klass anges ett typargument:

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

Datavetenskap (LTH) Föreläsning 2 VT 2020 19 / 55

Varför generiska klasserBakgrund

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

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

Men vi vill inte ha en lista där vi kan sätta in objekt hur som helst.I en lista med heltal vill vi inte av misstag kunna sätta inString-objekt.

42 5 "abc" 5

Datavetenskap (LTH) Föreläsning 2 VT 2020 20 / 55

Generik upptäcker typfel

Generik hindrar oss att göra fel.I en lista av typen ArrayList<String> kan man bara sätta insträngar.

Kompilatorn kommer att upptäcka typfel. Ex:

List<String> myList = new ArrayList<String>();myList.add(123);

ger nu kompileringsfel. Listan myList får enligt sin deklaration endastinnehålla objekt av typen String.

Datavetenskap (LTH) Föreläsning 2 VT 2020 21 / 55

Exempel på en generisk klassjava.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 avklassen E (eller subklasser till denna) sättas in i listan.

Datavetenskap (LTH) Föreläsning 2 VT 2020 22 / 55

Exempel på en generisk klassjava.util.ArrayList, forts

Observera att inte alla metoder i ArrayList<E> har E som typparameter.T.ex. har sökmetoderna contains, indexOf och remove följandesignaturer:

public boolean contains(Object x);public int indexOf(Object x);public boolean remove(Object x);

Användare som inte känner till den exakta typen av ett element x skakunna anropa metoderna. Dock kommer man att få resultat true om ochendast om x finns i listan (och alltså även är av rätt typ).

Datavetenskap (LTH) Föreläsning 2 VT 2020 23 / 55

Restriktioner för typargument

Typargumentet får inte vara av primitiv typ:

List<int> list = new ArrayList<int>(); // Går inte!

Istället får man använda motsvarande wrapperklass:

List<Integer> list = new ArrayList<Integer>();

I en lista av typen ArrayList<Integer> lagras alltså elementen i envektor med Integer-objekt:

0 21 3

42 5 5

4 65 7 8 9

Datavetenskap (LTH) Föreläsning 2 VT 2020 24 / 55

Primitiva datatyper - wrapperklasser

Primitiva typer i Java:

booleanshortintlongcharbytefloatdouble

Motsvarande wrapperklasser:

BooleanShortIntegerLongCharacterByteFloatDouble

Datavetenskap (LTH) Föreläsning 2 VT 2020 25 / 55

Primitiva datatyper - wrapperklasserExempel

int a = 42;Integer b = Integer.valueOf(42);

42

b42a

Variabeln a har värdet 42, medan variabeln b innehåller en referens till ettInteger-objekt.

Datavetenskap (LTH) Föreläsning 2 VT 2020 26 / 55

Diskutera

1. Kan vi skriva så här?Integer b = 42;

2. Fungerar detta?List<Integer> list = new ArrayList<Integer>();list.add(5);int j = list.get(0);

Listan innehåller Integer-objekt.På andra raden sätter vi in ett element i listan. Vad har det för typ?På tredje raden har vi deklarerat en variabel j av typen int. Men vad ärdet för typ på det som returneras av get?

Datavetenskap (LTH) Föreläsning 2 VT 2020 27 / 55

Autoboxing – unboxing

Autoboxing automatisk konvertering från primitiv typ till objekt avmotsvarande wrapperklass

Unboxing automatisk konvertering av objekt av wrapperklass tillmotsvarande primitiva typ

Exempel:int a;Integer b = 42; // autoboxinga = b; // unboxing

b = b + 1; // Unboxing av b för att beräkna b+1.// Därefter autoboxing av resultatet vid// tilldelningen.

Datavetenskap (LTH) Föreläsning 2 VT 2020 28 / 55

Autoboxing – unboxingi samband med generiska klasser

Praktiskt när man vill använda en generisk klass för att lagra element avprimitiv typ. Ex:

ArrayList<Integer> list = new ArrayList<Integer>();list.add(5); // Autoboxing till Integer-objekt här....int j = list.get(0); // Unboxing till int här.

Datavetenskap (LTH) Föreläsning 2 VT 2020 29 / 55

Generisk klass med flera typparametrar

Exempel: Interfacet Map<K, V> och klassen HashMap<K, V> har tvåtypparametrar.

K som i key, V som i value

Exempel på användning:

Map<String, Integer> map = new HashMap<String, Integer>();map.put("April", 30);

Datavetenskap (LTH) Föreläsning 2 VT 2020 30 / 55

Exempel på användning av klassen Map

Map<String, Integer> map = new HashMap<String, Integer>();map.put("Januari", 31);map.put("Februari", 28);map.put("Mars", 31);map.put("April", 30);map.put("Maj", 31);...

System.out.println("Antal dagar i mars: " + map.get("Mars"));

Datavetenskap (LTH) Föreläsning 2 VT 2020 31 / 55

Implementering av generiska klasser

Man kan deklarera en eller flera typparametrar när man definierar enklass:

public class ArrayList<E> {...}

Typparametrarna deklareras inom < > efter klassnamnet.En typparameters namn brukar bestå av en versal (stor bokstav).E som i element, T som i type . . .

Typparametrarna ersätts av ett typargument (ett klassnamn) närman använder den generiska klassen:

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

Datavetenskap (LTH) Föreläsning 2 VT 2020 32 / 55

Icke-generisk listaRisk för fel

I tidigare versioner av Java fanns inte generik. Istället användes typenObjekt som generell typ.

Klasen Object är superklass till alla andra klasser.En variabel av typen Object kan referera till vilka slags objekt somhelst.

Man kan fortfarande använda ArrayList utan typargument, kallasgrundtyp (eng. raw type). Problemet är att man kan blanda olika slagsobjekt hur som helst i listan.

ArrayList list = new ArrayList();list.add("41");list.add("42");list.add(43); // Ok, men förmodligen fel

Datavetenskap (LTH) Föreläsning 2 VT 2020 33 / 55

Icke-generisk listaArrayList, skiss av implementering

public class ArrayList {private Object[] data;private int size;

public ArrayList() {data = new Object[10];

}

public boolean add(Object e) { ... }

public Object get(int i) {...}}

Datavetenskap (LTH) Föreläsning 2 VT 2020 34 / 55

Generisk listaArrayList<E>, skiss av implementering

public class ArrayList<E> {private E[] data;private int size;

public ArrayList() {data = (E[]) new Object[10];

}

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

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

<E> är deklarationen av typparametern E.När klassen används ersätts E av en riktig klass, t.ex. Integer:

Datavetenskap (LTH) Föreläsning 2 VT 2020 35 / 55

Restriktioner för typparametrar

Typparametrar kan inte användas för att skapa objekt:public class SomeClass<E> {

E e = new E(); // FEL...

En vektor som ska användas internt i den generiska klassen kan skapasså här:

data = (E[]) new Object[10];

(I en metod som ska returnera en vektor bör man istället användametoden Array.newInstance.)

Datavetenskap (LTH) Föreläsning 2 VT 2020 36 / 55

Diskutera

Antag att vi lagrar ett antal tal i en samling element, t ex en lista eller enmängd:

List<Integer> list = new ArrayList<Integer>();// här sätts tal in i listan

Set<Integer> set = new HashSet<Integer>();// här sätts tal in i mängden

Hur ska vi göra för iterera genom en samling element och behandla allaelementen (t.ex. summera talen i listan respektive mängden)?

Datavetenskap (LTH) Föreläsning 2 VT 2020 37 / 55

Iteratorer

För att iterera genom (traversera) listor eller andra samlingar kan mananvända ett iteratorobjekt.Ett iteratorobjekt håller reda på en position i listan:

Datavetenskap (LTH) Föreläsning 2 VT 2020 38 / 55

IteratorerInterfacet Iterator<E>

Ett iterator-objekt är en instans av en klass som implementerarinterfacet Iterator<E>.

public interface Iterator<E> {/** Returns true if the iteration has more elements. */boolean hasNext();

/** Returns the next element in the iteration.Throws NoSuchElementException if the iterationhas no more elements. */

E next();

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

default void remove();

...}

Datavetenskap (LTH) Föreläsning 2 VT 2020 39 / 55

Användning av iteratorExempel

Summera talen i listan list av typen ArrayList<Integer>:

Iterera genom listan med explicit iterator:Iterator<Integer> itr = list.iterator();int sum = 0;while (itr.hasNext()) {

int n = itr.next();sum += + n;

}

Samma sak med for-each-sats:int sum = 0;for (int n : list) {

sum += n;}

Datavetenskap (LTH) Föreläsning 2 VT 2020 40 / 55

Iteratorer – under huven

Till ArrayList<E> hör en speciell iteratorklass (vars namn vi inte vet).Denna iteratorklass implementerar interfacet Iterator<E>. Iiteratorklassen finns attribut som håller reda på iteratorns position.I klassen ArrayList<E> finns en metod iterator() som returneraren referens till ett nyskapat iteratorobjekt.

listitr

0

...

Datavetenskap (LTH) Föreläsning 2 VT 2020 41 / 55

Användning av iteratorVanliga fel

Iteratorobjektet skapas inuti metoden iterator().Iterator<Integer> itr = new Iterator(); // FELIterator<Integer> itr = list.iterator(); // RÄTT

För varje anrop av next() hoppar iteratorn fram ett steg i listan.while (itr.hasNext()) {

if (itr.next() > 0) { // FEL - next anropas flera gångersum = += itr.next();

}}

while (itr.hasNext()) {int n = itr.next(); // RÄTTif (n > 0) {

sum = += n;}

}

Datavetenskap (LTH) Föreläsning 2 VT 2020 42 / 55

Interfacet Iterable<E>

I Java finns också 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(). Man kan alltså använda eniterator på objekt av alla dessa klasser.

Datavetenskap (LTH) Föreläsning 2 VT 2020 43 / 55

Java Collections Framework – interface hierarkimed 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

<<Interface>>Deque

Datavetenskap (LTH) Föreläsning 2 VT 2020 44 / 55

Interfacet ListIterator

I klasser som implementerar interfacet List finns även dessa metoder:

/** Returnerar en listiterator som startar i pos i. */public ListIterator listIterator(int i);

/** Returnerar en listiterator som startar i pos 0. */public ListIterator listIterator();

ListIterator<E> är ett interface som ärver Iterator<E> och där manlagt till metoder för att röra sig även bakåt i listor samt för att sätta inelement.

Datavetenskap (LTH) Föreläsning 2 VT 2020 45 / 55

Interfacet ListIterator

<<Interface>>Iterator

<<Interface>>ListIterator

public interface ListIterator<E> extends Iterator<E> {boolean hasPrevious();E previous();void add(E x);...

}

Datavetenskap (LTH) Föreläsning 2 VT 2020 46 / 55

foreach-sats i JavaExempel

ArrayList<String> words = new ArrayList<String>();// här sätts String-objekt in listan words...for (String s : words) {

// behandla s}

Ett sätt att enkelt iterera över samlingar. Man slipper att explicitanvända en iterator. Men hasNext() och next() anropas ibakgrunden.for (String s : words) ... kan läsas som ”för varje s i words”.Kan användas för objekt av klasser som implementerar Iterable ochför vektorer.

Datavetenskap (LTH) Föreläsning 2 VT 2020 47 / 55

foreach-satsVektorer

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

Ex: En metod som skriver ut alla strängarna i en vektor av typ String[]:

public void print(String[] a) {for (String s : a) {

System.out.println(s);}

}

Datavetenskap (LTH) Föreläsning 2 VT 2020 48 / 55

foreach-satsBegränsningar

Foreach-sats kan inte användas när man explicit behöver tillgång tilliteratorn i koden. T.ex. vid borttagning av element under itereringen:

Iterator<Integer> itr = list.iterator();while (itr.hasNext()) {

if (itr.next() < 0) {itr.remove();

}}

OBS! Man får inte använda listans egna metoder för att lägga till ellerta bort element under itereringen.

Använd iteratorns metod remove istället.

Listans metod removeIf kan också användas.

Datavetenskap (LTH) Föreläsning 2 VT 2020 49 / 55

foreach-satsBegränsningar

Foreach-sats kan inte användas för att iterera parallellt över flerasamlingar, 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());}

Datavetenskap (LTH) Föreläsning 2 VT 2020 50 / 55

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 finns ivektorn first och str2 finns i vektorn second. first och second är avtypen String[] :

for (String f : first ) {for (String s : second) {

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

}

Datavetenskap (LTH) Föreläsning 2 VT 2020 51 / 55

Traversera elementen i en samlingUtanför kursen, men kul att veta

Fr.o.m. Java 8 finns metoden forEach i interfacet Iterable.Exempel:

ArrayList<Integer> list = new ArrayList<Integer>();list.add(10);list.add(11);list.add(12);list.forEach(e -> System.out.println(e)); // skriver ut alla tallist.forEach(e -> { // skriver ut alla jämna tal

if (e % 2 == 0) {System.out.println(e);

}});

Det som skicka med som argument till metoden forEach är ettlambdauttryck – ett stycke kod som, i det här fallet, ska utföras förvarje element i listan. (Lambdauttryck behandlas senare under kursen.)

Datavetenskap (LTH) Föreläsning 2 VT 2020 52 / 55

Filtrering med metoden removeIfUtanför kursen, men kul att veta

I interfacet Collection finns metoden removeIf som kan användas föratt filtrera bort element ur en lista.

Exempel 1: Filtrera bort alla negativa tal ur listan list:

list.removeIf(n -> n < 0);

Exempel 2: Filtrera bort alla udda tal ur listan list:

list.removeIf(n -> n % 2 != 0);

Argumentet är ett lambdauttryck (behandlas senare under kursen).

Datavetenskap (LTH) Föreläsning 2 VT 2020 53 / 55

StrömmarUtanför kursen, men kul att veta

Man kan även använda strömmar för att behandla alla element i en samlingeller en vektor.

Exempel 1: Skriv ut alla personerna i listan pList:

pList.stream().forEach(p -> System.out.println(p));

Exempel 1: Skriv ut alla personer i listan pList som matchar x:

pList.stream().filter(p -> p.equals(x)).forEach(p ->System.out.println(p));

Du kan läsa mer om strömmar här:https://docs.oracle.com/javase/tutorial/collections/streams/

Datavetenskap (LTH) Föreläsning 2 VT 2020 54 / 55

Exempel på vad du ska kunna

Förklara begreppet abstrakt datatypHa kännedom om några viktiga abstrakta datatyper och vad somutmärker demHa kännedom om Java Collection FrameworkFörklara begreppet generik, kunna använda och implementerageneriska klasserFörklara begreppen wrapperklass, autoboxing och unboxingAnvända en iterator för att traversera en samling element

Datavetenskap (LTH) Föreläsning 2 VT 2020 55 / 55