Survey							
                            
		                
		                * Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Sammansatta datatyper
Generics: Parametrisk polymorfism
jonas.kvarnstrom@liu.se – 2016
2
Enligt TDDD73:
"Listan är en mycket användbar sammansatt datatyp.
I många andra språk kallar man listor för arrayer."
Många språk har både listor och arrayer!
Exakta definitioner varierar…
Listor (i Java):
Implementerade som klasser
Finns många varianter (olika lagring)
Kan växa och krympa
Arrayer (i Java):
"Inbyggda" i språket
En enda variant
Fixerad storlek
jonkv@ida
Listor och arrayer
4
För varje typ T kan Java dynamiskt skapa motsvarande arraytyp T[]
 Exempel: Object[], String[], Circle[]
 Subklass till Object
▪  Arrayer har metoder och fält, inte bara element
Object
Object[]
String[]
Circle[]
Circle[][]
jonkv@ida
Arrayer 1: Arraytyper
5
numbers
Circle[] circles = new Circle[10];
int[] numbers = new int[rnd()];
Arrayer skapas med new
Storlekar är fasta, men sätts vid körning
int second = numbers[1];
Element hämtas ut med index (första = 0)
for (int i = 0; i < numbers.length; i++) {
System.out.println(numbers[i]);
}
Index: 0…length-1
Arrayer känner till sin egen längd
int val = numbers[42000];
Indexkontroll: Ger
ArrayIndexOutOfBoundsException
Object
header:
length
[0]
[1]
[41]
(data)
42
0
0
0
Element
initialiseras:
0, 0.0, null,
eller false
jonkv@ida
Arrayer 2: Användning
6
Objektarrayer innehåller pekare:
 Circle[ ] circles = new Circle[10];
circles
Object
header:
length
[0]
[1]
(data)
10
[9]
Kan peka på vilken Circle
som helst, inklusive
subklasser (GraphicCircle)
Element initialiseras till null
Inga nya Circle-objekt skapas!
jonkv@ida
Arrayer 3: Pekar-arrayer
Att initialisera en array
7
Antal element: Implicit
▪ public static void main(String[ ] args) {
int[ ] numbers = new int[ ] { 1, 2, 4, 8, 16 };
print(numbers);
print(new int[ ] { 44, getRandomInt() });
}
Kompileras till kod!
Motsvarar:
int[ ] temp = new int[2];
temp[0] = 44;
temp[1] = getRandomInt();
print(temp);
Kompileras till kod!
Motsvarar:
int[ ] numbers = new int[5];
numbers[0] = 1;
numbers[1] = 2;
numbers[2] = 4;
numbers[3] = 8;
numbers[4] = 16;
jonkv@ida
Arrayer 4: Ange element
Arrayer av arrayer:
 Square[ ][ ] board
 Square[ ] row
 Square pos
board
row
= new Square[20][10];
= board[19];
= board[1][0];
Object
header:
length
[0]
[1]
(data)
20
8
Object
header:
length
[0]
…
[9]
Object
header:
length
[0]
…
[9]
(data)
10
(data)
10
[18]
[19]
Object
header:
length
[0]
…
[9]
(data)
10
jonkv@ida
Arrayer 5: Flerdimensionella arrayer
9
Arrayer ärver metoder från Object
 Av historiska anledningar: Bara default-implementationerna
Default-implementationer…
equals() testar identitet
int[ ] ar1 = new int[3]; // 0, 0, 0
int[ ] ar2 = new int[3]; // 0, 0, 0
System.out.println(ar1.equals(ar2));
// false
Kan inte ändras:
Bakåtkompatibilitet!
Vad vi oftast vill
Hjälpmetoder i java.util.Arrays
int[ ] ar1 = new int[3]; // 0, 0, 0
int[ ] ar2 = new int[3]; // 0, 0, 0
System.out.println(Arrays.equals(ar1,ar2));
// true
Också i java.util.Arrays: sort(),
binarySearch(), copyOfRange(),
deepToString(), hashCode(), fill(), …
jonkv@ida
Arrayer 6: Tillgängliga metoder
10
Arrayer ärver metoder from Object
 Av historiska anledningar: Bara default-implementationerna
Default-implementationer…
toString(): typnamn + ID
System.out.println(new int[10].toString());
// [I@3effd44e
System.out.println(new Circle[4]
.toString());
// [LCircle;@2b78146d
Vad vi oftast vill
Hjälpmetoder i java.util.Arrays
System.out.println(
Arrays.toString(new int[10]));
// [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
jonkv@ida
Arrayer 7: toString()
Styrka: Effektiv användning av minne
11
numbers
 Liten konstant "startkostnad",
12–20 bytes
 Plus elementens "verkliga" kostnad
▪ Kan använda byte / short
Styrka: Snabbt
 Element 40:
Minnesadress = [arraystart+12] + 40 * 4
Svaghet: Kan inte ändra längd när den har skapats!
 Saknar metoder som add(), append(), remove(), …
Object
header:
length
[0]
[1]
[41]
(data)
42
0
0
0
jonkv@ida
Arrayer 8: Styrkor och svagheter
Listor:
 Variabel storlek  bekvämt att använda!
 Inget stöd i språket, men i klassbiblioteken
För bättre förståelser för listor och generics:
 Vi visar en möjlig implementation
 Använder en array internt
 Måste byta ut arrayen när element läggs till
13
jonkv@ida
Listor 1: Intro
14
public class StringList {
private String[] elements;
private int
size;
Använder en array för lagring!
public StringList() {
this.elements = new String[8];
this.size = 0;
}
Allokerar lite extra plats
Hur många av platserna är använda?
StringList strings = new StringList();
strings
Object
header:
elements
size
(data)
0
Object
header:
length
[0]
[1]
[7]
(data)
8
jonkv@ida
Listor 2: En listklass
15
public void add(String element) {
elements[size] = element;
size++;
}
StringList strings = new StringList();
strings.add("Hello");
strings
Object
header:
elements
size
(data)
1
Object
header:
length
[0]
[1]
(data)
8
[7]
Vad händer när arrayen blir full?
"Hello"
jonkv@ida
Listor 3: En listklass (forts.)
public void add(String element) {
if (size == elements.length) {
int newsize = 2*size;
String[] arr2 = new String[newsize];
System.arraycopy(…);
this.elements = arr2;
}
elements[size] = element;
size++;
}
16
Är interna lagringen full?
Skapa större array,
kopiera innehållet,
kasta bort gamla arrayen!
jonkv@ida
Listor 4: En listklass (forts.)
public String get(int index) {
if (index < 0 || index >= size) {
throw new
IndexOutOfBoundsException();
} else {
return elements[index];
}
}
17
Kolla index:
Tillåt inte get(4) när size==2!
jonkv@ida
Listor 5: En listklass (forts.)
18
Effektiv representation – för de flesta operationer…
public void insert(int index, E element) {
if (size == elements.length) { … allocate more memory … }
}
System.arraycopy(elements, index, elements, index + 1, size - index);
elements[index] = element;
size++;
A B C D E F G H
list.add(2, "X");
A B C C D E F G H
Kopiera – tar tid!
A B X C D E F G H
Stoppa in
jonkv@ida
Listor 6: Stoppa in element
Vår listklass lagrar bara strängar!
public class StringList {
private String[] elements;
private int
size;
…
}
Behöver vi en listklass för varje elementtyp?
20
jonkv@ida
Elementtyper 1: Typspecifika listor?
21
public class ObjectList {
Array av Object-pekare,
private Object[] elements;
kan peka på objekt av godtycklig klass
private int size;
public ObjectList() {
this.elements = new Object[8];
this.size = 0;
}
public Object get(int index) {
if (index >= 0 && index <size) { return elements[index]; }
else /* Signal error */
}
public void add(Object element) {
if (size == elements.length) { /* Create a new array; copy old element */ }
elements[size] = element;
size++;
}
}
jonkv@ida
Elementtyper 2: Godtyckliga objekt
22
Nu får vi nya problem!
 1: Ingen typsäkerhet när vi adderar element!
▪ Vill ha en lista där vi stoppar in strängar:
ObjectList greetings = new ObjectList();
▪ Kan lägga in strängar:
greetings.add("hello");
▪ Kan råka lägga in cirklar också – inget fel vid kompilering eller körning!
greetings.add(new Circle(1, 1, 3));
public class ObjectList {
public ObjectList() { … }
public Object get(int index) { … }
public void add(Object element) { … }
}
jonkv@ida
Elementtyper 3: Problem
23
 Problem 2: Ingen typinformation när vi hämtar element!
ObjectList greetings = new ObjectList();
greetings.add("hello");
greetings.add(new Circle(1, 1, 3));
…
String str = greetings.get(0);
// Kompileringsfel
String str = (String) greetings.get(0);
// OK
Vi måste tala om för kompilatorn:
"Jag vet att jag la en sträng på position 0 – jag lovar!"
Krävs en cast – extra arbete för oss
public class ObjectList {
public ObjectList() { … }
public Object get(int index) { … }
public void add(Object element) { … }
}
jonkv@ida
Elementtyper 4: Problem
 Problem 3: Tänk om vi har fel!
ObjectList greetings = new ObjectList();
greetings.add("hello");
greetings.add(new Circle(1, 1, 3));
for (int i = 0; i < greetings.size(); i++) {
String str = (String) greetings.get(i);
// Runtime error for i=1 – it’s a Circle!
}
Upptäcks inte när programmet kompileras
24
jonkv@ida
Elementtyper 5: Problem
void printMult3() {
for (int i = 1; i <= 13; i++) {
System.out.println(3 * i);
}
}
void printMult5() {
for (int i = 1; i <= 13; i++) {
System.out.println(5 * i);
}
}
void printMult(int num) {
for (int i = 1; i <= 13; i++) {
System.out.println(num * i);
}
}
void printMult4() {
for (int i = 1; i <= 13; i++) {
System.out.println(4 * i);
}
}
26
num är en
heltalsvariabel
Kan ha värdet
3, 4, 5, 8, …
void printMult8() {
for (int i = 1; i <= 13; i++) {
System.out.println(8 * i);
}
}
jonkv@ida
Vanliga parametrar till metoder
class ListOfString {
String[] elements;
int
length;
{…}
String get(int index)
void add(String element) { … }
}
class MyList<E> {
E[]
elements;
int
length;
E
get(int index)
void add(E element)
}
class ListOfCircle {
Circle[] elements;
int
length;
{…}
Circle get(int index)
void add(Circle element) { … }
}
27
class ListOfShape {
Shape[] elements;
int
length;
{…}
Shape get(int index)
void add(Shape element) { … }
}
E är en
typvariabel
{…}
{…}
Kan ha värdet
String, Shape, …
class ListOfButton {
Button[] elements;
int
length;
{…}
Button get(int index)
void add(Button element) { … }
}
jonkv@ida
Typparametrar till klasser
28
Generiska typer med typparametrar
class MyList<E> {
E[]
elements;
int
length;
E
get(int index)
void add(E element)
}
En array där elementen har typ E
– verkliga typen är inte angiven än
{ return elements[index]; }
{ … } // Takes a parameter of type E
 Kan "instansieras" med olika typer som parameter
MyList<String> – nästan exakt som:
class MyList<String> {
String[] elements;
int
length;
{…}
String get(int index)
void add(String element) { … }
}
MyList<Shape> – nästan exakt som:
class MyList<Shape> {
Shape[] elements;
int
length;
{…}
Shape get(int index)
void add(Shape element) { … }
}
jonkv@ida
Generics 1: Intro
class MyList<E> {
E[] elements;
int length;
E get(int index)
void add(E element)
}
29
{ return elements[index]; }
{…}
 En lista där E=String:
MyList<String> greetings = new MyList<String>();
greetings.add("hello");
// OK
greetings.add(new Circle(1, 1, 3));
// Compile-time error: add(String)
String str = greetings.get(0);
// No cast needed: String get(int index)
 En lista där E=MyList<String>  en lista av listor!
MyList<MyList<String>> lists = new MyList<MyList<String>>();
lists.add(greetings);
jonkv@ida
Generics 2: Användningsexempel
class MyList<E> {
E[] elements;
int length;
E get(int index)
void add(E element)
}
{ return elements[index]; }
{…}
 Mycket repetition:
MyList<MyList<String>> listor = new MyList<MyList<String>>();
 Syntaktiskt socker: Diamant-operatorn (betyder "samma som förut")
MyList<MyList<String>> listor = new MyList<>();
DRY-principen: Don’t RepeatYourself!
Regelbrott är WET: Write Everything Twice…
30
jonkv@ida
Generics 3: Att skriva mindre
class MyList<E> {
E[] elements;
int length;
E get(int index)
void add(E element)
}
{ return elements[index]; }
{…}
 Man kan använda en generisk typ utan att ange typparametrar:
MyList listor = new MyList(); // Defaultvärde för E blir Object
 Enbart för kompatibilitet med gammal kod!
▪ Generics kom redan 2004
▪ Gammal kod borde fortfarande gå genom kompilatorn, men med varningar
▪ Gör inte detta i ny kod!
31
jonkv@ida
Generics 4: "Råa" typer
Kallas generisk programmering, ger oss parametrisk polymorfism
 Samma namn (MyList)
 Olika beteende (beroende på typparameter)
Jämför med subtypspolymorfism
 Samma metodnamn, flera implementationer inom en typhierarki
 Olika implementation väljs dynamiskt, beroende på verklig objekttyp
32
Jämför med ad-hoc-polymorfism (overloading)
 Samma metodnamn, flera implementationer i samma klass
 Olika implementation väljs statiskt, beroende på statiska parametertyper
jonkv@ida
Parametrisk polymorfism
En typparameter
måste ange en objekttyp!
class List<E> {
E[]
elements;
int
length;
E
get(int index)
void add(E element)
}
{…}
{…}
List<String> strings; // OK
List<Button> buttons; // OK
List<int> numbers; // Does not work!
34
…för egentligen
skapas bara en klass!
class List {
Object[] elements;
int
length;
{…}
Object get(int index)
void
add(Object element) { … }
}
Kompilatorn
tar hand om resten
Sparar minne…
men int är inget Object!
jonkv@ida
Typparametrar och objekttyper
35
Hur skapar vi en listklass som accepterar heltal?
Implementera om strukturerna?
class IntArrayList {
private int[] elements;
private int length;
public int get(int index) {
return elements[index];
}
void add(int element) { … }
}
Repetera för 8 primitiva typer
och för varje datastruktur
Kan göras – finns färdiga bibliotek
på nätet (GNU Trove, …)
Använd wrappers!
public class Integer {
private final int value;
public Integer(int value) {
this.value = value;
}
public int intValue() {
return value;
}
}
Repetera för 8 primitiva typer
 klart
jonkv@ida
Wrappers 1: Intro
Det finns en wrapper-klass för varje primitiv datatyp
36
jonkv@ida
Wrappers 2: Wrapper-objekt
37
För att skapa wrapper-objekt:
 Kan använda vanlig konstruktor
Number ten = new Integer(10);
Number pi = new Double(3.14);
 Bättre: Använd statiska fabriksmetoden valueOf()
Number ten = Integer.valueOf(10);
Number pi = Double.valueOf(3.14);
Sparar tid och minne: Återanvänder objekt för vanliga värden!
public class Integer {
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
Fungerar för att wrappers är immutable:
}
Värden kan inte ändras
}
jonkv@ida
Wrappers 3: Skapa
Resulterar i objekt  kan lagras i listor, objektpekare, …
List<Number> numbers = new ArrayList<>();
numbers.add(Integer.valueOf(10));
numbers.add(Double.valueOf(3.14));
Det är BARA då vi behöver wrappers!
Använd int, double, … i normalfallet!
För att hämta ut värdet: Anropa typeValue()
Number intobj
int val0
= numbers.get(0);
= intobj.intValue();
double val1
= numbers.get(1).doubleValue();
38
jonkv@ida
Wrappers 4: Användning
Kan använda automatisk boxing och unboxing
 ("Paketinslagning")
List<Number> numbers = new ArrayList<>();
numbers.add(10);
numbers.add(3.14);
double val1 = numbers.get(1);
VARNING: Osynlig ineffektivitet!
 Kan skapa nya objekt
 Tar (lite) extra tid att plocka ut värden ur objekt
 Vissa rekommenderar explicit boxing / unboxing istället
39
jonkv@ida
Wrappers 5: Användning
int[] numbers = new int[]
{ 12, 14 ,16, 18, 20 }
List<Integer> list = new ArrayList<>();
list.add(12); list.add(14); list.add(16); list.add(18); list.add(20);
Array
Object
header:
length
[0]
[1]
[4]
(data)
5
12
14
20
Wrappers ger mindre
andel overhead om
strukturerna är mer
komplexa…
40
jonkv@ida
Wrappers 6: Använder mer minne
ArrayList
Object
header:
size
arr
Object
header:
length
[0]
[1]
[4]
5
Object
header:
value
(data)
Object
header:
value
(data)
(data)
12
(data)
14
5
Object
header:
value
(data)
20
Python har inga primitiva typer, bara objekttyper
 Trevligare på ytan – slipper bry sig om skillnaden
 Vanliga heltal har metoder!
▪ >>> x = 10
▪ >>> x.bit_length()
4
▪ >>> x.__add__(10)
20
 I Java: Kan välja mellan
▪ Primitiva typer – inte objekt, vissa begränsningar
▪ Wrapperklasser – är objekt, men långsammare, kräver mer minne
41
jonkv@ida
Wrappers 7: Python?
Java Collections Framework
jonas.kvarnstrom@liu.se – 2016
43
Collections Framework: Många sammansatta datastrukturer
 1) Uppsättning gränssnitt för listor, köer, mängder, mappningar
 De viktigaste:
Kom ihåg: Gränssnitt ger oss frihet att välja implementation!
jonkv@ida
Collections Framework 1: Intro
 2) En uppsättning implementationer
44
jonkv@ida
Collections Framework 2: Intro
 3) Några hjälpklasser
45
jonkv@ida
Collections Framework 3: Intro
Collection<E>: Generell samling av objekt
 Vissa samlingar är ordnade
▪ Listor har ett första element –
inte mängder
 Vissa tillåter dubblerade element
▪ Listor kan innehålla två identiska element –
inte mängder
47
jonkv@ida
Collection 1: Intro
48
 Lägga till element:
▪ c.add(E)
▪ c.addAll(Collection)
 Testa innehåll:
▪ c.isEmpty(), c.size()
▪ c.contains(Object obj)
▪ c1.containsAll(Collection c2)
– Alla element i c2 finns i c1?
 Hämta alla element:
▪ c.toArray()
– En Object[ ] som innehåller samma element
 Ta bort element:
▪ c.clear()
▪ c.remove(Object)
– Tar bort alla element
jonkv@ida
Collection 2: Grundläggande funktionalitet
49
List<E> extends Collection<E>
 Alltid ordnad: Element har index
 Implementeras av
▪ ArrayList
– Mycket vanlig, implementation liknar våra tidigare exempel
▪ LinkedList
– Ganska vanlig, andra egenskaper
▪ Stack, Vector
– Använd inte, deprecated
jonkv@ida
List 1: Intro
50
Principen bakom länkade listor:
LinkedList
Object
header:
size
first
(data)
5
ListNode
Object
header:
next
prev
value
Object
header:
value
(data)
(data)
12
En extra listnod per element
 använder mer minne
ListNode
Object
header:
next
prev
value
Object
header:
value
(data)
(data)
14
ListNode
Object
header:
next
prev
value
Object
header:
value
(data)
(data)
16
jonkv@ida
Länkade listor (1)
ListNode
Object
header:
next
prev
value
Snabbt att skjuta in / ta bort värden
LinkedList
Object
header:
size
first
(data)
5
ListNode
Object
header:
next
prev
value
Object
header:
value
Object
header:
value
(data)
(data)
12
ListNode
Object
header:
next
prev
value
Object
header:
value
(data)
(data)
14
51
(data)
(data)
15
ListNode
Object
header:
next
prev
value
Object
header:
value
(data)
(data)
16
jonkv@ida
Länkade listor (2)
52
Tar lång tid att ta fram värde nummer n i listan
LinkedList
Object
header:
size
first
(data)
5
ListNode
Object
header:
next
prev
value
Object
header:
value
(data)
(data)
12
ListNode<E> get(int index) {
ListNode<E> x = first;
for (int i = 0; i < index; i++)
x = x.next;
return x;
}
ListNode
Object
header:
next
prev
value
Object
header:
value
(data)
(data)
14
ListNode
Object
header:
next
prev
value
Object
header:
value
(data)
(data)
16
jonkv@ida
Länkade listor (3)
53
 Hämta / hitta element
▪ list.get(index)
▪ list.indexOf(Object needle), list.lastIndexOf(Object needle)
▪ Collections can hitta dellistor, göra binärsökning, hitta min/max-element
 Lägga till och ta bort
▪ list.add(E value)
– ärvs från Collection!
▪ list.add(int index, E value) – flyttar element efter givet index
▪ list.addAll(int index, Collection c)
▪ list.remove(int index)
 Ändra element
▪ list.set(int index, E value)
▪ Collections kan söka/ersätta, fylla med ett värde, kopiera listor
 Omarrangera listor
▪ Collections kan blanda, sortera, rotera, reversera listor
jonkv@ida
List 2: Metoder
54
Arrayer används:
 För att implementera datatyper
 ArrayList måste använda en
“primitiv” array
 När varje nanosekund spelar roll
 Bara efter CPU-profilering som visar
att listhantering spelar roll
Listor används:
 Nästan alltid!
 Många hjälpfunktioner tillgängliga
 Kan lätt lägga till och ta bort
element, osv
 Används av många klasser i Javas
klassbibliotek
 …
 När varje byte spelar roll
 Bara efter minnesprofilering…
 Ibland om storleken är fixerad
 Om storleken varierar:
Låt listorna hantera detta!
Tetrislabben använder arrayer
eftersom Board-storleken
är fixerad!
jonkv@ida
List 3: Listor vs. arrayer
55
Queue<E> extends Collection<E>
 Kan lägga till i slutet av kön
 Kan ta bort i början av kön
 Implementeras av
▪ ArrayDeque, LinkedList
– grundläggande köstrukturer
 Varianter
▪ Deque: Även "på andra sidan" (Double-Ended QUEue)
▪ PriorityQueue
– har element i sorterad ordning
Vad händer om det är omöjligt?
Operation
Stoppa in element
Ta bort element
Se på första elementet
Signalerar fel – exception
add(e)
remove()
element()
Returnerar speciellt värde
offer(e)
poll()
peek()
jonkv@ida
Queue 1: Köer
56
Map<K,V> är Javas motsvarighet till dictionaries
 Associerar nycklar/keys K med värden V
 Vanlig klass, inte "språkfiness"  mer att skriva
>>> dict = {'a': 45, 'b': 39, 'c': 19}
>>> dict['a']
45
>>> dict['d'] = 4711
>>> dict
{'a': 45, 'c': 19, 'b': 39, 'd': 4711}
>>> len(dict)
4
▪ TreeMap
▪ HashMap
public static void main(String[] args) {
Map<Character,Integer> dict = new HashMap<>();
dict.put('a', 45);
dict.put('b', 39);
dict.put('c', 19);
System.out.println(dict.get('a'));
// 45
dict.put('d', 4711);
System.out.println(dict);
// {a=45, b=39, c=19, d=4711}
System.out.println(dict.size());
// 4
}
– sorterar elementen, måste ange sorteringsordning
– kräver hashkoder, förklaras i TDDD86
jonkv@ida
Map: Mappningar
Hur kan man iterera över alla element i en samling?
 Med en array eller ArrayList fungerar index utmärkt:
static boolean contains(List<?> haystack, Object needle) {
for (int i = 0; i < haystack.size(); i++) {
if (haystack.get(i).equals(needle)) return true;
}
return false;
}
58
jonkv@ida
Iteration 1: Med index
59
Hur kan man iterera över alla element i en samling?
 Med en LinkedList fungerar index, men långsamt:
static boolean contains(List<?> haystack, Object needle) {
for (int i = 0; i < haystack.size(); i++) {
if (haystack.get(i).equals(needle)) return true;
}
return false;
}
Node<E> get(int index) {
Node<E> x = first;
for (int j = 0; j < index; j++)
x = x.next;
return x;
}
get(0):
get(1):
get(2):
get(3):
get(4):
…
Gå genom element j=0
Gå genom element j=0, 1
Gå genom element j=0, 1, 2
Gå genom element j=0, 1, 2, 3
Gå genom element j=0, 1, 2, 3, 4
jonkv@ida
Iteration 2: Med index
Hur kan man iterera över alla element i en samling?
 Med en generell Collection (eller Set) finns inga index!
static boolean contains(Collection<?> haystack, Object needle) {
for (int i = 0; i < haystack.size(); i++) {
if (haystack.get(i).equals(needle)) return true;
}
return false;
}
Vi är egentligen inte intresserade av index!
Vi vill veta:
Finns det fler element?
Vad är nästa element?
60
jonkv@ida
Iteration 3: Utan index
61
Lösning: Gränssnittet Iterator
public interface Iterator<E> {
public boolean hasNext();
public E next();
…
}
Finns det fler element?
Vad är nästa element?
static boolean contains(Iterator<?> haystack, Object needle) {
while (haystack.hasNext()) {
Specialsyntax:
Object element = haystack.next();
Iterator för vilken elementtyp som helst
if (element.equals(needle))
return true;
Vet inte vilken elementtyp… men:
}
Det är i alla fall någon sorts Object!
return false;
}
Har en egen implementation för varje datastruktur,
eget sätt att hålla reda på "var vi är just nu"
jonkv@ida
Iteration 4: Iterator
62
Gränssnittet Iterable säger att objektet kan ge oss en iterator
public interface Iterable<E> {
public Iterator<E> iterator();
}
Implementeras av Collections och arrayer, kan användas i for
static boolean contains(Collection<?> haystack, Object needle) {
for (Object element : haystack) {
Loopen anropar haystack.iterator()
if (element.equals(needle)) return true;
}
Anta haystack är LinkedList
return false;
}
LinkedList.iterator() returnerar new
LinkedListIterator(), som vet hur man
int sum(int[] numbers)
effektivt itererar över länkade listor
for (int i : numbers) { … }
}
void printAll(List<String> greetings) {
for (String str : greetings) { … }
}
jonkv@ida
Iteration 5: Iterable och for(each)-loopar
Om man ändrar en samling medan man itererar över den:
 ConcurrentModificationException
 Har inget att göra med multitrådning!
static boolean contains(Iterable<?> haystack, Object needle) {
for (Object element : haystack) {
if (element.equals(needle)) return true;
if (…) {
ändra i haystack …
}
}
return false;
}
jonkv@ida
Iteration 6: ConcurrentModificationException 63
Iterator har en tredje metod
package java.util;
public interface Iterator<E> {
public boolean hasNext();
public E next();
public void remove();
}
Ta bort elementet
som just returnerades av next()
static void removeAllCopies(Iterable<String> haystack, Object needle) {
Iterator<String> iter = haystack.iterator();
while (haystack.hasNext()) {
String element = haystack.next();
if (element.equals(needle)) {
iter.remove();
}
}
}
Tas bort via iteratorn  ingen ConcurrentModificationException
64
jonkv@ida
Iteration 7: Ta bort element
65
jonkv@ida
"Fortsättning" i nästa kurs
Mer om datastrukturer:
 TDDD86 Datastrukturer, algoritmer och programmeringsparadigm,
http://kdb5.liu.se/liu/lith/studiehandboken/svkursplan.lasso?&k_budget_year=2016&k_ku
rskod=TDDD86