Du er ikke logget inn. Så lenge du ikke er logget inn går du glipp av muligheten for å holde styr på din egen progresjon.

Filtrering:

07.01: Grensesnittet Comparable<T>

a) Skriv en klasse Katt. En katt skal ha et navn og en alder, i tillegg til en metode for å hente ut informasjon om klassen (for eksempel toString()).

b) Vi ønsker å kunne sammenlikne kattene basert på alder. For å gjøre dette skal vi bruke Java-grensesnittet Comparable, som krever implementasjon av metoden public int compareTo. I vårt tilfelle skal vi sammenlikne Katt-objekter. Dersom alderen til katten vi sjekker mot er høyere enn alderen til katten der metoden blir kalt, skal vi returnere et negativt tall (for eksempel -1). I motsatt tilfelle skal vi returnere et positivt tall (for eksempel 1). Dersom alderen til de to kattene er lik skal vi returnere 0.

c) Skriv et hovedprogram der du oppretter en liste (velg selv type) som du fyller med noen Katt-objekter med noen forskjellige navn og aldere, og bruk en for-løkke og compareTo-metoden for å finne ut hvem som er eldst.

a + b:

class Katt implements Comparable<Katt> {
    private String navn;
    private int alder;

    public Katt(String navn, int alder) {
        this.navn = navn;
        this.alder = alder;
    }

    public int compareTo (Katt annen) {
        if (this.alder < annen.alder) {
            return -1;
        } else if (this.alder > annen.alder) {
            return 1;
        } else {
            return 0;
        }
    }

    public String toString() {
            return "Katten " + navn + ", alder: " + alder;
    }

Merk at vi her også kan velge å gjøre compareTo mer spesifikk slik at vi også finner hvor stor forskjell det er mellom de verdiene vi sammenlikner:

public int compareTo (Katt annen) {
        return this.alder - annen.alder;
    }

c:

import java.util.ArrayList;

class SammenlignKatt {
        public static void main(String[] args) {

        ArrayList<Katt> katteliste = new ArrayList<>();

        Katt anne = new Katt("Anne", 4);
        Katt liss = new Katt("Liss", 8);
        Katt beate = new Katt("Beate", 3);

        katteliste.add(anne);
        katteliste.add(liss);
        katteliste.add(beate);

        Katt eldst = katteliste.get(0);
        for (Katt k : katteliste) {
            if (k.compareTo(eldst) > 0) {
                eldst = k;
            }
        }

        System.out.println(eldst);
    }
}

07.02: Grådig beholder

I denne oppgaven skal vi lage en generisk beholder som kan holde på akkurat ett element. Vi skal også kunne bytte ut elementet i beholderen, slik at det som var der fra før av returneres når det nye settes på plass.

Men! Beholderen er grådig, og krever at dersom vi legger inn et nytt element skal dette være av minst like høy "verdi" som det vi tok ut. For å kunne vite om elementet er av høyere verdi krever beholderen at det som skal legges inn må implementere grensesnittet Comparable. Vi må altså kunne sammenlikne det som legges i boksen med andre elementer av samme type.

I tillegg trenger vi selve metoden som forsøker å sette inn et element. Dersom beholderen er tom fra før av skal vi sette inn objektet og deretter returnere null. Deretter skal vi sjekke om det som settes inn er har like høy eller høyere "verdi" enn det som allerede er i boksen. Hvis det stemmer skal det nye elementet settes inn og det gamle returneres. Hvis det nye objektet ikke er verdifullt nok skal metoden bare returnere null.

I tillegg skal beholderen ha en metode for å returnere (men ikke ta ut) det den holder på for øyeblikket.

Skriv en slik beholder, og lag et testprogram som forsøker å sette inn noen elementer av gitt, sammenlignbar type (for eksempel Katt fra oppgave 7.01 eller klassen String) og sjekker at det ikke går an å sette inn et element med lavere verdi.

class GraadigBeholder < T extends Comparable < T>> {
T mittElement;

    public T settInn (T ny) {
        if (mittElement == null) {
            mittElement = ny;
            return null;

        } else if (ny.compareTo(mittElement) >= 0) {
            T midlertidig = mittElement;
            mittElement = ny;
            return midlertidig;

        } else {
            return null;
        }
    }

    public T seInnhold() {
        return mittElement;
    }
}

07.03: Dobbeltlenket liste

I denne utfordringsoppgaven skal vi anvende vår kunnskap om generiske klasser (klasser med parametere) på en lenkeliste. Du skal opprette en dobbeltlenket liste som kan holde på objekter av vilkårlig type. I en dobbeltlenket liste er alle elementer lenket sammen med både det neste og det forrige elementet i lista. Hver node trenger med andre ord både en neste-peker og en forrige-peker.

a) Lag en klasse DobbelLenke som tar en generisk parameter . Klassen skal inneholde en indre privat klasse Node.

b) La Node inneholde en peker Node neste og Node forrige. Node-klassen skal også inneholde en peker til T data. Det er nodene som skal lenkes sammen i din lenkeliste. Legg til slutt inn en peker til Node forste i den ytre klassen (altså DobbelLenke).

c) Nå trenger du en metode for å sette inn data i listen. Lag en metode public void settInn(T element) i DobbelLenke-klassen. Dersom førstepekeren er null, skal du opprette en node med element som data-innhold, og la denne være første element i listen. Er førstepekeren ikke null, skal du gå via første-pekeren, innover i listen, og finne det siste elementet. Etter dette, setter du inn den nye noden. Husk å sette den nye nodens forrige-peker til det nest siste elementet, og det nest siste elementets neste-peker til å peke til noden.

Her er det mange pekere, og det er viktig å holde tungen rett i munnen! Blir det for mye å holde styr på, kan det være en god idé å lage en enkeltlenket liste først, og siden utvide til doble lenker. Tegn gjerne enkle datastrukturtegninger underveis!

class DobbeltLenketListe<T> {

    Node start = null;
    int antall = 0;
    private class Node {
        T data;
        Node neste = null;
        Node forrige = null;
        Node(T data) {
            this.data = data;
        }
        void settNeste(Node neste) {
            this.neste = neste;
            neste.settForrige(this);
        }
        void settForrige(Node forrige) {
            this.forrige = forrige;
        }
        Node hentNeste() {
            return neste;
        }
        Node hentForrige(){
            return forrige;
        }
        T hentData(){
            return data;
        }
    }



    public void settInn(T element) {
        Node nyNode = new Node(element);
        if (antall == 0) { //ingen elementer i listen
            start = nyNode;
        }
        else {
            Node node = start;
            while (node.hentNeste() != null) {
                node = node.hentNeste();
            }
            node.settNeste(nyNode);
            nyNode.settForrige(node);
        }
        antall++;
    }

    public void skrivUt() {
        Node node = start;
        while (node != null) {
          System.out.println(node.hentData());
          node = node.hentNeste();
        }
    }
}

07.04: Arraybasert liste med Iterator

1) Implementér klassen EnkelArrayListe. Listen trenger kun å holde på String-objekter. Listen skal inneholde et array, og elementene i listen puttes på neste ledige plass i arrayen når de blir lagt til. For enkelhets skyld vil vi ikke tillate sletting fra listen, kun innlegging. La også listen ha en bestemt kapasitet som konstruktøren tar som parameter. Du trenger ikke implementere utvidelse av kapasiteten.

2) La listen være itererbar. Den må altså implementere grensesnittet java.util.Iterable med medfølgende implementasjon av java.util.Iterator. Se forelesningsmateriell fra forelesningene om beholdere eller kapittel 15.2 i Big Java for en oppfrisker på bruk av iteratorer.

import java.util.Iterator;

public class EnkelArrayListe implements Iterable<String> {
    private String[] arr;
    private int maksStorrelse;
    private int storrelse = 0;

    @SuppressWarnings("unchecked")
    public EnkelArrayListe(int maksStorrelse) {
        this.maksStorrelse = maksStorrelse;
        arr = new String[maksStorrelse];
    }

    public void leggTil(String strengen) {
        if (storrelse >= maksStorrelse) {
            throw new IllegalStateException("Ikke plass til flere");
        }
        arr[storrelse++] = strengen;
    }

    public Iterator<String> iterator() {
        return new ListeIterator();
    }

    private class ListeIterator implements Iterator<String> {
        private int gjeldendeIndeks = 0;

        public String next() {
            return arr[gjeldendeIndeks++];
        }

        public boolean hasNext() {
            return gjeldendeIndeks < storrelse;
        }
    }
}

07.05 Sorter med ArrayList

Merk: til denne oppgaven trenger du klassen Katt fra 7.01
I denne oppgaven skal vi bruke en ArrayList til å sortere objekter.

a) Definer en klasse sortertArrayList. Den skal ha en generisk ArrayListe slik at vi kan putte in objekter og sortere dem. Klassen skal ha en settInn (T data) metode slik at vi kan sette in data i listen. Skriv også en hentUtFørste metode som fjerner og returnerer første element fra listen.

Nå har vi lagd en sortertArrayList hvor vi kan sette inn objekter og hente ut den første. Siden vi må sortere listen, må vi kunne sammenligne objekter.

b) Du må endre på klassedefinisjonen slik at bare sammenlignbare objekter kan settes inn, med andre ord, slik at bare objekter som er Comparable kan legges in i listen.

Siden alle objektene som nå legges inn er Comparable, har de en compareTo metode. Vi vil sortere objektene slik at de med minst verdi legges in forrest i listen.

c) Skriv om settInn metoden slik at objekter legges inn på riktig plass, objektet med minst verdi skal forrest i listen. Gå gjennom alle objektene i listen og finn plassen hvor objektet passer inn ved å bruke compareTo metoden til objektet. Finn plassen ved å sjekke om objekter før har <= verdi den data som blir sendt som parameter, og/eller sjekk om objekter etter har verdi > enn data. Husk å legge til objektet på slutten av listen hvis det alle objekter i listen allerede har mindre verdi enn objektet.

Hint: bruk .get(index) og add(index, element) metodene til ArrayList

Nå er ArrayListen alltid sortert siden vi sorterer med en gang vi setter objekter inn i listen.

d) Test programmet ditt med et main program. Her skal du bruke Katte objekter fra oppgave 7.01. Opprett en sortertArrayList og lag minst. 4 katter med forskjellig alder og sett dem inn i listen (prøv innsetting i forskjellige rekkefølger). Etter du har satt inn alle kattene, må du hente ut en katt om gangen og skrive den ut.
Prøv med andre typer (Integer, String, osv.) også.

a) + b) + c)

class SortertArrayList<T extends Comparable<T>> {
    ArrayList<T> list = new ArrayList<>();

    public void settInn(T data) {
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i).compareTo(data) > 0) {
                list.add(i, data);
                return;
            }
        }
        list.add(data);
    }
    public T hentFørste(){

        return list.remove(0);
    }
}

d)

class Hovedprogram {
    public static void main(String[] args) {
        SortertArrayList<Katt> katter = new Hovedprogram().new SortertArrayList<>();
        katter.settInn(new Katt("a", 5));
        katter.settInn(new Katt("b", 3));
        katter.settInn(new Katt("c", 1));
        katter.settInn(new Katt("d", 10));
        for (int i = 0; i < 4; i++) {
            System.out.println(katter.hentFørste());
        }
    }
}

07.06 Itererbar Butikk

Merk: denne oppgaven bygger på Trix-oppgave 6.04!

I denne oppgaven skal vi gjøre klassen Butikk itererbar, slik at vi kan bruke en for-each-løkke til å gå gjennom Person-objektene i en Butikk.

a) Gjør nødvendige endringer i klassen Butikk for at den skal være itererbar. Butikk må altså implementere grensesnittet Iterable, med medfølgende implementasjon av Iterator.

Hint: for at klassen Butikk skal implementere Iterable kan vi skrive:

class Butikk implements Iterable<Person>{}

Hint 2: grensesnittet Iterable krever at man implementerer metoden iterator som returnerer et Iterator-objekt. Du må derfor også skrive en klasse PersonIterator:

class PersonIterator implements Iterator<Person>{}

Vi kan nå iterere gjennom Person-objektene i en Butikk. Derfor skal vi nå i hovedprogrammet(TestButikk) skrive ut informasjon om hver Person i køen ved å bruke en for-each-løkke, istedenfor å bruke metoden «gaaTilKassen».

b) Skriv ut informasjon om hver Person i køen, ved hjelp av en For-each-løkke i hovedprogrammet.

a)

import java.util.Iterator;

class Butikk implements Iterable<Person>{
    private Person foerste;

    public void settInn(Person p) {
        if (this.foerste == null) {
            this.foerste = p;
        } else {
            Person midlertidig = foerste;
            while (midlertidig.hentNeste() != null) {
                midlertidig = midlertidig.hentNeste();
            }
            midlertidig.settNeste(p);
        }
    }

    public Iterator<Person> iterator(){
      return new PersonIterator();
    }

    class PersonIterator implements Iterator<Person>{
      private Person denne;

      public PersonIterator(){
        denne = foerste;
      }

      @Override
      public boolean hasNext(){
        return denne != null;
      }

      @Override
      public Person next(){
        Person midl = denne;
        denne = denne.hentNeste();
        return midl;
      }
    }
}

b)

class TestButikk {
    public static void main(String[] args) {
        Butikk butikken = new Butikk();

        butikken.settInn(new Person("Stig", "Sitronsaft"));
        butikken.settInn(new Person("Hedda", "Engangskopper"));
        butikken.settInn(new Person("Jawad", "Pasta"));
        butikken.settInn(new Person("Henrik", "Kaffe"));
        butikken.settInn(new Person("Mathias", "Tomatsuppe"));

        System.out.println("BUTIKK-KØ: ");
        for(Person p : butikken){
          System.out.println(p);
        }
    }
}

07.07: CD-samling

1) Skriv en klasse CDAlbum. CDAlbum skal implementere Comparable og skal ha følgende instansvariabler:

  • Artistnavn
  • Albumnavn
  • Utgivelsesår

I tillegg trenger CDAlbum en metode for å hente artistnavn og en implementasjon av toString()-metoden der all informasjon om albumet skrives ut på én linje.

2) Implementer også metoden compareTo(CDAlbum). Et CDAlbum skal kunne sammenliknes med et annet ved hjelp av albumets artistnavn, slik at en plate av Megadeth kommer etter et album av Major Parkinson, men før et album av Metallica.

3) Skriv et program som kan sortere en CD-samling. Du får samlingen utdelt som en tekstfil cdliste.txt (denne finner du her). Programmet skal kunne lese inn en tekstfil som et argument når programmet kjøres. For å gjøre dette må du bruke liste-parameteret fra main-metoden (oftest kalt args). Dette kan leses inn i terminal når programmet kjøres, slik:

> java Hovedprogram innfil.txt

Deretter skal programmet lese inn hver linje sortert til en ArrayList.

4) Skriv ut den sorterte listen i hovedprogrammet.

5) (Vanskelig) Utvid programmet slik at det også lagrer det sorterte innholdet til en tekstfil (og la igjen brukeren velge filnavn når programmet starter).

import java.util.*;
import java.io.*;

class CDSamling {
    public static void main(String[] args) {

        ArrayList<CDAlbum> cdsamling = lesOgSorter(args[0]);

        for (CDAlbum a : cdsamling) {
            System.out.println(a);
        }

        skrivTilFil(cdsamling, args[1]);
    }

    public static ArrayList<CDAlbum> lesOgSorter(String filnavn) {

        File f = new File(filnavn);
        Scanner fscan = null;
        try {
            fscan = new Scanner(f);
        }
        catch (FileNotFoundException e) {
            System.out.println("Fant ikke filen!");
            return null;
        }

        ArrayList<CDAlbum> liste = new ArrayList<CDAlbum>();

        while (fscan.hasNextLine()) {
            String[] linje = fscan.nextLine().split(",");

            CDAlbum nytt = new CDAlbum(linje[0], linje[1], linje[2]);

            boolean sattInn = false;
            int teller = 0;

            while (teller < liste.size() && !sattInn) {
                if (nytt.compareTo(liste.get(teller)) < 0) {
                    liste.add(teller, nytt);
                    sattInn = true;
                }
                teller++;
            }

            if (!sattInn) {
                liste.add(nytt);
            }
        }
        return liste;
    }

    public static void skrivTilFil(ArrayList<CDAlbum> liste, String utfil) {

        File f = new File(utfil);
        try {
        PrintWriter pw = new PrintWriter(f);

        for (CDAlbum cd : liste) {
            pw.append(cd.toString()+ "\n");
        }
        pw.close();

        } catch (FileNotFoundException e) {
            System.out.println(e.getMessage());
        }

    }
}