Observera att detta är en arbetsversion av sidan!
Dölj style3dev.css för att bli av med annoteringarna!

Lektion 9.   Obligatorisk redovisning 4.

Moment: Samverkande klasser, läsa och skriva filer samt använda ArrayList, instickssortering.
Arbetssätt: Skriv och testa ut klasserna i tur och ordning:
  1. klassen Tombola som övar på användning av arraylistor,
  2. klassen Person med bl a equals- och compareTo-metoder,
  3. klassen PersonList med läsning av data från fil samt instickssorteringar och
  4. klassen Lottery som kombinerar ovanstående klasser.
Uppskattad arbetstid 8 tim
Redovisning Redovisas enligt datum på kurssidan.

Förberedelser

Klassen Tombola

Tombola En tombola är ett lotteri med ett tombolahjul. Tombolahjulet består av en roterande trumma som fylls med hoprullade lotter. Trumman är försedd med en vev som man roterar trumman med och därmed blandar lotterna. Genom en lucka i trumman drar spelaren en lott.

Skriv en klass Tombola som simulerar dragning utan återläggning. Tombolan lagrar lotter som numrerade från 1 till n. Man skall kunna dra ett antal lotter på så sätt att ett draget nummer inte kommer att dras igen.

Klassen skall ha följande metoder:

Metoder i klassen Tombola
public Tombola(int n) Konstruktor som skapar en tombola med n lotter och fyller den med lotter numrerade 1 till n
public int draw() Drar ett nummer ur tombolan och returnerar det. Detta nummer skall inte kunna returneras igen förrän tombolan återfyllts. Om alla lotter dragna skall ett RuntimeException kastas (se lektion 8).
Tips: Läs på om metoden remove(int i) i klassen ArrayList.
public void fill() Tömmer tombolan om den inte är tom. Återfyller den sedan med det antal lotter den skapades för. Tips: Titta på dokumentationen för ArrayList för att se hur man enkelt tömmer en sådan.
public boolean isEmpty() Returnerar true om tombolan är tom (alla lotter dragna), annars false
public String toString() Returnerar en sträng som representerar aktuellt tillstånd för tombolan dvs hur många lotter den rymmer och vilka lotter som finns kvar.
public static void main(String[] args) Demonstrerar användning av övriga metoder.

Det skall naturligtvis gå att skapa flera olika tombolaobjekt av olika storlek i samma program!

Tips

  1. Använd en ArrayList för att hålla reda på lotterna!
  2. Slumpa ett index, inte ett lott-värde. Tag den lott som ligger på det slumpade indexet.
  3. Metoden size() i klassen ArrayList returnerar aktuellt antal lagrade värden.
  4. Metoden remove både tar bort och returnerar det borttagna objektet.

Klassen Person

Skriv en klass Person som representerar en person (fysisk eller juridisk) med uppgift om namn, adress och ålder. (Du kan utgå från den klass du skrev i lektion 5 och modifiera den så att den stämmer med nedanstående.)

Klassen skall innehålla:

Metoder i klassen Person
public Person(String name, String address, int age) Konstruktor
public String getName() Returnerar personnamnet
public String getAddress() Returnerar adressen
public int getAge() Returnerar åldern
public int compareTo(Person p) Används för att bestämma hur två personer kommer i bokstavsordning på namn.
Skall returnera
  • ett negativt värde om denna (this) person kommer före personen p,
  • ett positivt värde om p kommer före denna person och
  • 0 om personerna har samma namn.
Ingen speciell hänsyn behöver tas till nationella tecken (å, ä, ö, ü, ê, ...).

Tips: Använd metoden compareTo som finns i String-klassen!

public boolean equals(Person p) Returnerar true om denna (this) person har samma namn, samma adress och samma ålder som personen p, annars false.

Tips: Metoden equals (eller compareTo) i klassen String

public String toString() Returnerar en sträng av typ (namn, adress, ålder). Om åldern är negativ skall åldersdelen utelämnas.
public static void main(String[] args) Demonstrerar användning av övriga metoder.

Tips:

  1. Utgå från den Person-klass du haft i tidigare lektioner.
  2. Kom ihåg att använda equals och compareTo för att jämföra String-objekt!

Klassen PersonList

Klassen PersonList skall representera ett antal personer. Eftersom man inte vet hur många poster som skall lagras så passar även här en ArrayList bra.

Personlistan skall kunna fyllas med data från en fil. På filen består en personpost av tre rader - den första raden innehåller namn, den andra adress och den tredje ålder (se filen som du kopierade i början).

Specifikation av klassen PersonList:
Metoder i klassen PersonList
public PersonList() Konstruktor som skapar en tom lista (utan Person-objekt)
public int getSize() Returnerar antalet personobjekt som finns i listan.
public void add(Person p) Lägger in personen p sist i listan
public void addNameSorted(Person p) Lägger in personen p i listan. Metoden förutsätter att listan är sorterad på namn och ska lägga in den nya personen så att den förblir sorterad på namn. (Om listan inte skulle vara sorterad spelar det ingen roll var den nya personen hamnar.)
public void addAgeSorted(Person p) Lägger in personen p i listan. Metoden förutsätter att listan är sorterad i stigande ålder dvs med den yngsta först. Den ska lägga in den nya personen så att den förblir sorterad i stigande ålder. (Om listan inte skulle vara sorterad spelar det ingen roll var den nya personen hamnar.)
public void load(String filename) Läser in personuppgifter, skapar och lägger in Person-objekt i listan. Filformatet beskrivs nedan.
public Person get(int i) Returnerar person på plats i
public PersonList nameSorted() Skapar och returnerar en ny personlista i namnordning utifrån den aktuella listan.
public PersonList ageSorted() Skapar och returnerar en ny personlista i åldersordning utifrån den aktuella listan.
public String toString() Returnerar en sträng med hela listans innehåll
public void print() Skriver hela listan en personpost per rad. Använd toString-metoden för de enskilda personposterna!
public static void main (String[] args) Demonstrerar användning av övriga metoder.

Kom ihåg att använda equals och compareTo för att jämföra String-objekt!

Tips:

  1. Skriv och testa konstruktor, add, getSize, get och toString.
  2. Skriv och testa load.

    Hur man läser (och skriver) filer på ett enkelt sätt finns beskrivet i en minilektion.
    Du kan även ha nytta av att titta på sista exemplet i minilektionen om Scanner-klassen.

    Metoden kan förorsaka ett så kallat IOExecption och måste deklareras så här:

    public void load(String filename) throws IOException {

    Även metoder som anropar denna metod (troligen main) måste deklareras med throws.

    Av erfarenhet vet vi att det kan vara svårt att göra rätt i denna metod. Lägg in utskriftssatser i inläsningsloopen så att du ser hur långt du kommer och vilka rader som tolkas som namn, adress respektive ålder.

  3. Skriv och testa addAgeSorted.

    Den snyggaste implementationen är att skriva en while-loop som bara beräknar vilket index personen ska placeras på. Loopen skall alltså stanna när platsen är funnen. Därefter gör man en addition på platsen med detta index. På det sättet behöver man inga specialfall för första eller sista plats eller för att listan är tom från början.

    Man bör alltid kunna se på loopvillkoret när loopen ska sluta. Satsen break är ofta en ful nödlösning! Om du upptäcker att du vill använda break så bör du försöka formulera om loopvillkoret!

  4. Skriv och testa addNameSorted. Använd compareTo i Person-klassen för att jämföra objekten.
  5. Tänk på att använda metoderna addNameSorted och addAgeSorted när du skriver metoderna nameSorted och ageSorted!

Filformat

Varje person upptar tre rader i filen. Första raden innehåller namnet, andra raden innehåller adressen och den tredje åldern.

Exempel på hur raderna i filen kan se ut:
Kalle Anka Ankeborgsvägen 123 37 Tenzing Norgay Mount Everest 100 Arthur Dent Guildford 42

Tips: Användbara Scanner-metoder: hasNextLine, nextLine, hasNextInt och nextInt.

Observera: Metoden nextInt byter inte rad efter att ett heltal lästs. Man måste alltså byta rad med ett nextLine innan man kan läsa nästa namnrad.

Klassen Lottery

Skriv en klass Lottery med en main-metod som skapar ett personregister utifrån den givna filen med personuppgifter (persons.utf8, persons.latin1, ...) samt en tombola med lika många lotter som personer i filen. Fråga sedan användaren om hur många lotter som skall dras och skriv ut vinnarna i bokstavsordning. Om en lott med nummer i dras så vinner personen som ligger på plats i-1 (i en ArrayList). Kom ihåg att lotterna är numrerade från 1 men posterna från 0!


Gå till nästa lektion eller gå tillbaka

Valid CSS!