Listor 16 4 Listor Tema: Listor, listimplementeringar - enkellänkad lista, sorterad lista, interfacet Comparable. Litteratur: Avsnitt 2.1–2.3, 2.5–2.7, 2.9-2.10 (avsnitt 4.1–4.5, 4.8 i gamla upplagan). Läs också bilderna från föreläsning 3. Använda ArrayList och LinkedList – skugga equals U 28. I kursen arbetar vi bland annat med klasser och interface från Java Collections Framework. Ett exempel på sådana är interfacet List samt klasserna ArrayList och LinkedList i paketet java.util. I klasserna ArrayList och LinkedList finns metoder för att hitta ett element i listan, contains(Object), indexOf(Object) och remove(Object). Hur avgörs om två element är ”lika”? Vem bestämmer vad som menas med ”lika” (den som implementerat listklassen eller den som använder klassen) och hur gör man det? U 29. Antag att vi ska lagra böcker i en lista av någon av dessa typer. En bok beskrivs av följande klass: public class Book private String private String private String { isbn; title; author; public Book(String isbn, String title, String author) { this.isbn = isbn; this.title = title; this.author = author; } public String toString() { return author + ": " + title; } } En bok identifieras av sitt ISBN-nummer. Gör de förändringar i klassen Book som behövs för att metoderna contains, indexOf och remove ska fungera som förväntat. U 30. Antag att vi har deklarerat följande lista och lagt in ett antal böcker av typen Book i listan: List<Book> list = new ArrayList<Book>() // satser för att lägga in böcker i listan Lägg till sats/er för att ta reda på om boken med ISBN-nummer ”9780345917430” finns i listan. Enkellänkad lista I några av uppgifterna används klasserna SingleLinkedList och ListNode: public class SingleLinkedList<E> private ListNode<E> first; /** Creates an empty list. */ public SingleLinkedList() { first = null; } { Listor 17 /** Inserts the specified element at the beginning of this list. */ public void addFirst(E e) { ListNode<E> n = new ListNode<E>(e); n.next = first; first = n; } ... /* Nested class. Represents a node which contains an element of type E. */ private static class ListNode<E> { private E element; private ListNode<E> next; /* Creates a listnode which contains e. */ private ListNode(E e) { element = e; next = null; } } } U 31. Skriv programrader som skapar ett lista av typen SingleLinkedList för att lagra heltal samt ser till att listan innehåller talen 1, 2, 3. U 32. a) Lägg till följande metod i klassen SingleLinkedList: /** Returns the first element in this list. Throws NoSuchElementException if this list is empty. */ E getFirst(); b) Lägg till följande metod i klassen SingleLinkedList: /** Returns the last element from this list. Throws NoSuchElementException if this list is empty. */ E getLast(); U 33. Lägg till följande metod i klassen SingleLinkedList: /** Returns true if this collection contains the specified element. */ public boolean contains(Object x); U 34. Lägg till följande metod i klassen SingleLinkedList: /** Removes the first occurrence of the if it is present. If this list does Returns true if this list contained if this list changed as a result of boolean remove(Object e); specified element from this list, not contain the element, it is unchanged. the specified element (or equivalently, the call). */ Ledning: • Utgå från din lösning på uppgift U 33. • Tänk på att du för att kunna ta bort ett element måste ha en referens till föregående element i listan. Håll därför reda både på aktuellt element och dess föregångare när du går framåt i listan under sökningen. • Tänk på specialfallen (tom lista, det är första elementet som ska tas bort ...). Listor 18 Implementering genom delegation U 35. I läroboken, kapitel 2, finns en implementering av en klass OrderedList som representerar en följd av element, sorterad i växande ordning. Klassen har följande utformning: public class OrderedList<E extends Comparable<E>> implements Iterable<E> { private LinkedList<E> theList; public OrderedList() { theList = new LinkedList<E>(); } public void add(E obj) { ListIterator<E> itr = theList.listIterator(); while (itr.hasNext()) { if (obj.compareTo(itr.next()) < 0) { itr.previous(); itr.add(obj); return; } } itr.add(obj); } public E get(int index) { return theList.get(index); } public Iterator<E> iterator() { return theList.iterator(); } public int size() { return theList.size(); } } I metoden add ser man till att listan blir sorterad i storleksordning genom att leta upp rätt position för objektet obj. Övriga metoder utför sin uppgift genom att ”delegera” till motsvarande operation i klassen LinkedList (som visas i koden ovan för metoderna get, iterator och size). Varför implementerar man inte OrderedList genom att ärva från klassen LindkedList<E> enligt följande mönster? public class OrderedList<E extends Comparable<E>> extends LinkedList<E> U 36. Lägg till metoden remove i klassen OrderedList. Tänk på utnyttja att listan är sorterad så att du inte undersöker onödigt många element. /** Removes the first occurrence of the if it is present. If this list does Returns true if this list contained if this list changed as a result of boolean remove(E obj); specified element from this list, not contain the element, it is unchanged. the specified element (or equivalently, the call). */ Listor 19 U 37. I OrderedList finns det en metod iterator som returnerar en Iterator för listan. Varför finns det inte också en metod listIterator som returnerar en ListIterator? Implementera interfacet Comparable U 38. I klassen OrderedList i uppgift U 35 anges typparametern på följande sätt: <E extends Comparable<E>> Vad innebär det? Skulle man istället kunna skriva bara <E>? U 39. Antag att vi ska använda klassen OrderedList i uppgift U 35 för att hålla reda på patienter som väntar på en akutmottagning. Varje patient tilldelas en prioritet, som är ett heltal. Ett lågt värde på detta attribut motsvarar hög prioritet. Patienter representeras av följande klass: public class Patient { private String firstname; private String lastname; private int prio; public Patient(String firstname, String lastname, int prio) { this.firstname = firstname; this.lastname = lastname; this.prio = prio; } ... } Se till att klassen implementerar gränssnittet Comparable<T>. Det är prioriteterna som ska jämföras här och inte namnen. Tänk också på att det är en god regel att också omdefiniera metoden boolean equals(Object x) som finns i superklassen Object så att dessa båda metoder är ense om när två objekt av klassen är lika. U 40. Hur ska metoden compareTo implementeras om man istället för prioritet ska jämföra namnen? Antag att man i första hand ska sortera efter efternamn.
© Copyright 2024