Files
oops/oppgavetekster/oving5/StringGrid.md
Andreas Omholt Olsen 55c36a603a Add oving 5
2026-02-09 15:28:09 +01:00

5.6 KiB

Interface - StringGrid-oppgave

Denne oppgaven handler om et grensnitt (interface) for rutenett som holder strenger (StringGrid), hvordan slike implementeres og hvordan en kan iterere gjennom et slikt rutenett ved hjelp av en Iterator.

I denne oppgaven tar vi utgangspunkt i et StringGrid-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:

Filene i denne oppgaven skal ligge i oving5/stringgrid.

package oving5.stringgrid;

/**
 * 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
    int getRowCount();

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

    // Returns the String at the given row and column. Throws an IllegalArgumentException if the
    // row or column is out of range
    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
    void setElement(int row, int column, String element);
}

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

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 JUnit-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). Du kan også bruke en enkel String[] eller en todimensjonal String[][] for å lagre strengene. Implementasjonen er helt opp til deg, så lenge den oppfører seg som beskrevet i grensesnittet.

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 rowMajor) - 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 er true) eller nedover først (rowMajor er false).
  • boolean hasNext() - returnerer true så lenge det er flere String-objekter igjen i StringGrid-objektet som ikke ennå er blitt iterert over (med andre ord, 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 (med andre ord, hvorvidt om rowMajor er true eller 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.

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-løkke 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: oving5/stringgrid/StringGridTest.java.