Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

Work in progress....

Excerpt

Denne oppgaven hander handler om et grensnitt (interface) for person-navn og rutenett som holder strenger (StringGrid), hvordan slike implementeres og sorteres med grensesnittet Comparatorhvordan en kan iterere gjennom et slikt rutenett ved hjelp av en Iterator.

...

I denne oppgaven tar vi utgangspunkt i en Person-klasse som har et navn (String) bestående av fornavn ("given name") og etternavn ("family name"). 

 

 

Grid-

...

 

-- De får utdelt GridImpl<T> og skal selv definere Grid<T>-grensesnittet og endre GridImpl så den implementerer Grid<T> (dersom vi tror bruk av generics forvirrer dem, så låser vi det til String, men da må testen oppdateres)

-- GridIterator<T> implementerer en Iterator<T> over alle elementene. Klassen kan konfigureres slik at den kan itererer bortover først (rowMajor=true) eller nedover først (rowMajor=false).

Del 1

Definer et grensesnitt Named med metodene 

  • setGivenName(String) og String getGivenName() for å sette og hente fornavn,
  • setFamilyName(String) og String getFamilyName() for å sette og hente etternavn, og
  • setFullName(String) og String getFullName() for å hente personens hele navn.

Del 2

Lag en Person-klasse som implementerer grensesnittet NamedPerson-klassen kan ha enten ett eller to felter for personnavnet avhengig av hva man finner enklest. Man kan anta at brukeren oppretter Person-objekter med gyldige navn, altså trenger man ikke å implementere valideringsmetoder.

 

Del 3

For å kunne sammenligne Named-objekter, f. eks. for å sortere en kontaktliste, kan vi lage en klasse NamedComparator som implementerer grensesnittet Comparator. NamedComparator-objektet skal brukes for å sammenligne navn parvis: Først på etternavn, og deretter på fornavn om etternavnene er like. Dette kan gjøres ved å la NamedComparator-klassen implementere metoden int compare(Named named1, Named named2) med følgende logikk: 

  • Dersom etternavnene er ulike skal metoden
    • returnere et negativt heltall om det første etternavnet er leksikografisk ordnet før det andre,
    • eller et positivt heltall i motsatt tilfelle.
  • Dersom etternavnene er like skal metoden gjøre det samme på fornavnene. Dersom også fornavnene er like skal metoden returnere 0.
  • Hint: For å sammenlikne to String-objekter kan man bruke String-klassens innebygde Comparable-metode int compareTo(String streng2). Denne metoden sammenlikner leksikografisk en streng med en annen.

 

 

Merk: Underveis i denne oppgaven skal det skrives testkode for å sortere navn i en liste vha. Collections.sort-metoden, for å teste om NamedComparator-klassen har implementert Comparator riktig.

JExercise-testkode for oppgavene finner du her: interfaces/NamedTest.java 

grensesnitt som definerer metodene til et rutenett som holder strenger. Et rutenett er firkantet og består av et antall rader og kolonner. Det skal være mulig å spørre rutenettet hvilken streng som er på angitt rad og kolonne i tillegg til å endre strengen på angitt rad og kolonne. Denne oppførselen er oppsummert i det definerte StringGrid-grensesnittet under:

Code Block
package interfaces;

/*
An interface with methods for managing the content of a String grid.
The grid has a number of rows (the grid's height) and columns (the grid's width).
In each cell in the grid there is a String that can be set with the setElement method and read with the getElement method.
*/
 public interface StringGrid {

	// Returns the number of rows in this StringGrid
	public int getRowCount();
	// Returns the number of columns in this StringGrid
	public int getColumnCount();

	// Returns the String at the given row and column. Throws an IllegalArgumentException if the row or column is out of range
	public String getElement(int row, int column);
	// Sets the String at the given row and column. Throws an IllegalArgumentException if the row or column is out of range
	public void setElement(int row, int column, String element);
}

Alle klasser som implementerer StringGrid-grensesnittet må støtte de fire definerte metodene.

Exercise-panelet  

Bruk av Exercise-panelet er obligatorisk for denne øvingen. Du må ha panelet åpent med StringGrid.ex-filen (tests > interfaces StringGrid.ex) i før du begynner med oppgaven. For mer informasjon/hjelp, se nederst på forrige side, altså hovedsiden for Øving 6.

Del 1 - StringGrid-grensesnitt og implementerende StringGridImpl-klasse

Lag en StringGridImpl-klasse som implementerer StringGrid-grensesnittet definert over. Merk at grensesnitt ikke kan brukes til å spesifisere konstruktører, så du må selv definere en eller flere egnede konstruktører. Det er imidlertid nødvendig å implementere en konstruktør som tilsvarer den JExercise-testen forventer:

  • StringGridImpl(int rows, int columnCount) - konstruktør som tar inn antall rader som rows og antall kolonner som columnCount.

Du står fritt til å velge hvordan metodene definert av grensesnittet skal implementeres så lenge de tilfredsstiller den definerte oppførselen. Hint: Bruk en enkel ArrayList<String> eller en dobbel ArrayList<ArrayList<String>> (se wiki-siden om todimensjonale matriser). 

Del 2 - StringGridIterator-klasse

Det er hensiktmessig å kunne iterere over alle elementene i et rutenett som implementerer grensesnittet StringGrid, f.eks. når en bygger en streng i en toString()-metode eller skal sjekke om et spill har blitt avsluttet / vunnet. I denne deloppgaven skal du lage en slik Iterator-implementasjon, kalt StringGridIterator. Denne klassen må implementere grensesnittet Iterator<String>, siden StringGrid inneholder String-objekter. I tillegg til metodene som er definert i Iterator-grensesnittet, må StringGridIterator ha en konstruktør som tar imot hvilken StringGrid det skal itereres over og i hvilken rekkefølge elementene skal returneres i. Disse verdiene må huskes, så koden i Iterator-metodene kan brukes dem til å styre iterasjonen. StringGridIterator-klassen må altså støtte følgende konstruktør / metoder:

  • StringGridIterator(StringGrid, boolean) - konstruktør som tar inn StringGrid-objektet som StringGridIterator-klassen skal iterere over i tillegg til en logisk verdi som angir om iterasjonen skal være bortover først (rowMajor=true) eller nedover først (rowMajor=false).
  • boolean hasNext() - returnerer true så lenge det er flere String-objekter igjen i StringGrid-objektet som ikke ennå er blitt iterert over (mao. sjekk om du har kommet til siste rute i rutenettet).

  • String next() - returnerer det neste String-objektet i rutenettet. Hvilken String som er den neste, avhenger av hvordan rutenettet skal itereres (mao. om rowMajor=true eller rowMajor=false).

  • void remove() - denne metoden skal bare utløse et unntak av typen UnsupportedOperationException siden det ikke skal være mulig å fjerne String-objekter fra rutenettet.

Del 3 - Iterable-grensesnittet

Endre StringGrid-grensesnittet slik at det utvider (med extends) Iterable<String>. Dette skal gjøre det mulig å skrive for-setningen under, for å gå gjennom alle elementene i rutenettet.

Code Block
StringGrid stringGrid = ... // her initialiseres stringGrid
// gå gjennom alle elementene i stringGrid
for (String s: stringGrid) {
	// gjør noe med s her
}

Rekkefølgen som en slik for-setningen går gjennom elementene på, skal være hele første rad, så hele andre rad osv. til og med siste rad.

Hva slags følger får det for StringGridImpl? Gjør nødvendige endringer i den også, og test at det virker!


Testkode for del 1 og del 2 finner du her: interfaces/StringGridTest.java. Originalkoden (jextest) for testen finner du her: interfaces/StringGrid.jextest

Include Page
Bunntekst for oppgaver
Bunntekst for
Include Page
Bunntekst for JExercise-oppgaverBunntekst for JExercise- oppgaver