Dynamiska datatyper
För att hålla ihop flera variabler hade vi hittills använd fält/array. En väl användbar datastruktur som har för vissa behov lite jobbiga begränsningar
-
Antal av element i en array sätt vid deklarationen och är konstant. Att överdeklarera är oftast ingen option.
-
Det 'kostar' rätt mycket att infoga ett värde eller ta bort ett värde. Även om det går så alla efterföljande element flyttas till nästa index. Kan ta länge vid stora array.
För att komma runt dessa begänsningar finns en gynsam datastruktur i Processing/Java (och i många andra språk):
Samlingar och listor
Dessa har precis det array saknas:
-
Obegränsad storlek
-
Inget problem att infoga ett element mitt i listan.
Det finns flera sorters listor i Processing/Java och alla har sina för- och nackdelar. LinkedList är smidigare när det gäller att infoga och ta bort element, ArrayList är snabbare när man söker ett visst element. Man borde välja efter behov. För många användningsfall finns optimerade lösningar som kö, stapel, träd eller ordbok (En översikt (engelska)). Vi kan inte går genom alla sorters samlingar och väljer här en som är smidigast:
LinkedList
Ett litet exempel hur man avända LinkedList. I det här programmet kan man mata in tal hur länge man vill tills man mata in -1:
import java.util.LinkedList; // behövs för användning
void setup() {
LinkedList<Integer> minLista = new LinkedList<Integer>(); //Deklarera en lista för heltalsvärden;
int tal = 0;
while ( tal != -1) { // håller på tills val lika med -1
tal = QuestionInt("Ange ditt heltal. Avsluta med -1"); // fråga
minLista.add(tal); // lägg till i slutet av listan
}
println("Du matade in " + minLista.size() + " tal" );
for(int i = 0; i < minLista.size() ; i++ ) {
int talet = minLista.get(i) ;
println( talet );
}
//ELLER
for(int talet : minLista) {
println(talet);
}
}
Översikt list-deklarationer:
OBS! Nu skrivs alla datatyper med stor bokstav i början
LinkedList<Integer> minLista = new LinkedList<Integer>(); // Heltal
LinkedList<Double> minLista = new LinkedList<Double>(); // decimaltal, hög precision
LinkedList<Float> minLista = new LinkedList<Float>(); // decimatal
LinkedList<String> minLista = new LinkedList<String>(); // strängar, textbitar
Laboration 1
-
Ta exemplet från ovan och plussa ihop alla värden i listan och skriv ut det.
-
Ändra exemplet så att de inmatade tal används för att rita staplar i med motsvarande längd.
-
Bygg om utgångsexemplet så att man kan mata in namn i stället för heltal. Inmatningen ska avslutas när man mata in "SLUT". För att jämföra två strängar gör man så här:
while( ! namn.equals("SLUT") ) { .....
.
Fler användbara metoder
Det finns en hel del metoder som hjälpa att bearbeta samlingen eller hämta information från de. Anta att samlingen minLista har fyllts på detta sätt:
LinkedList<String> minLista = new LinkedList<String>();
minLista.add("Element A");
minLista.add("Element B");
minLista.add("Element C");
minLista.add("Element D");
minLista.add("Element E");
minLista.add(1,"Element X");
println(minLista);
minLista.remove(2);
println(minLista);
println("Antal element: " + minLista.size() );
println(" Och på plats 3 finns elementet " + minLista.get(3) );
metod | förklaring |
---|---|
minLista.add( object ) |
Lägga till ett objekt i slutet av listan. objekt måste vara av samma typ som användes när List skapades. LinkedList<datatyp> minLista = new LinkedList<datatyp>(); |
minLista.add(index, object) |
Lägga till ett objekt på plats index. Alla objekt efter det flyttas till nästa plats. |
println(minLista); |
För en förenklad utskrikt räcker det att skriva println(minLista); . Då visas alla listelement, kommaseparerad. Inte särskild snygg med visa i alla fall innehållet. utskrift här: [Element A, Element X, Element B, Element C, Element D, Element E] |
objekt = minLista.get(index) |
läsa/hämta/returnera ett element från plats index. |
minLista.set(n, objekt); |
Ersätta ett värde på plats n med objekt. |
int antal = minLista.size(); |
size() returnera antal element i en lista. Samma funktion som .length för en array/fält. |
minLista.remove( index ) |
radera elementet på plats index. Till exempel minLista.remove(2); tar bort Element B, efter det finns Element C på tredje platsen: [Element A, Element X, Element C, Element D, Element E] . |
*objekt* = minLista.removeFirst(); *objekt* = minLista.removeLast() |
Returnera och radera första resp. sista object i listan. |
boolean fanns = minLista.removeFirstOccurrence(object); boolean fanns = minLista.removeLastOccurrence(object); |
Radera första resp. sista förkomsten av ett object i listan, men returnera true/false om den fanns i listan. |
Mer om LinkedList på www.tutorialspoint.com/java/util/java_util_linkedlist (på engelska)
Laboration 2
- Kopiera följande kod. Sedan ska programmet utökas så att alla positioner sparas i en LinkedList och används för att visa alla. Med varje musclick ska det kommer till en cirkel. Det kommer behövas två LinkedList
, en för x-koordinaten och en för y-koordinaten. i mousePressed-blocket ska det läggas till koordinater i listorna, i draw ska alla cirklar ritas i en loop.
import java.util.LinkedList;
//Variabler
int posX, posY;
void setup() {
size(500, 500);
fill(#FF0000);
textSize(24);
}
void draw() {
background(255);
ellipse(posX, posY, 35, 35 );
}
void mousePressed() {
posX = (mouseX+20) / 40*40;
posY = (mouseY+20) / 40*40;
}
-
Nu ska programmet visar bara de tio senaste click. Så med 11:te click försvinner det första.
-
Dessutom ska alla cirklar rörar sig långsam till höger .....
-
Och att cirklarna få en numrering ...
Värdefulla verktyg
Lägg till import java.util.Collections;
i början av kodfilen. nu finns tillgång till en stor verktygslåda! Låt oss säger att du har den här koden
import java.util.Collections; // verktygsbibliotek!!!
import java.util.LinkedList;
LinkedList<String> minLista = new LinkedList<String>();
minLista.add("Peter");
minLista.add("Gudrun");
minLista.add("Lovisa");
minLista.add("Elsa");
minLista.add("Lara");
println(minLista);
//nya verktyg
String first = Collections.min(minLista); //enligt lexikaliskt ordning
println(first);
Collections.sort(minLista);
println(minLista);
Collections.reverse(minLista);
println(minLista);