// Ett Java-program som testar några olika behållare, bland annat ArrayList import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; import java.util.HashSet; import java.util.TreeSet; import java.util.HashMap; import java.util.TreeMap; // Exempelobjekt att använda i testerna: hamstrar, båtar och telefonnummer class Hamster { private String name; public Hamster(String name) { this.name = name; } public String toString() { return "Hamster-" + name; } } class Båt { private String name; public Båt(String name) { this.name = name; } public String toString() { return "Båten " + name; } } // Två hamstrar kan ha samma namn, men ändå vara OLIKA hamstrar. // Två båtar kan ha samma namn, men ändå vara OLIKA båtar. // Men två telefonnummer kan inte ha olika siffror och ända vara olika telefonnummer. // Två telefonnummer som innehåller samma siffror, är SAMMA telefonnummer. // Därför är Telefonnummer-klassen lite krångligare, med "equals" mm. class Telefonnummer implements Comparable { private int landskod, riktnummer, abonnentnummer; public Telefonnummer(int landskod, int riktnummer, int abonnentnummer) { this.riktnummer = riktnummer; this.abonnentnummer = abonnentnummer; this.landskod = landskod; } public Telefonnummer(int riktnummer, int abonnentnummer) { this(46, riktnummer, abonnentnummer); } public Telefonnummer(int abonnentnummer) { this(46, 19, abonnentnummer); } public String toString() { return "+" + landskod + "-(0)" + riktnummer + "-" + abonnentnummer; } public int compareTo(Object o) { Telefonnummer rhs = (Telefonnummer)o; if (this.landskod < rhs.landskod) return -1; if (this.landskod > rhs.landskod) return 1; if (this.riktnummer < rhs.riktnummer) return -1; if (this.riktnummer > rhs.riktnummer) return 1; if (this.abonnentnummer < rhs.abonnentnummer) return -1; if (this.abonnentnummer > rhs.abonnentnummer) return 1; return 0; } public boolean equals (Object o) { if (!(o instanceof Telefonnummer)) return false; Telefonnummer rhs = (Telefonnummer)o; return this.landskod == rhs.landskod && this.riktnummer == rhs.riktnummer && this.abonnentnummer == rhs.abonnentnummer; } public int hashCode () { int result = 17; result = 37 * result + landskod; result = 37 * result + riktnummer; result = 37 * result + abonnentnummer; return result; } } // class Telefonnummer public class Datatest { public static void main(String[] args) { // []-arrayerna är enklast, // och ibland måste man använda dem, // när de används av bibliotek och inbyggda mekanismer // (som för main-funktionens argument) for (int i = 0; i < args.length; ++i) System.out.println("Argument " + i + ": '" + args[i] + "'"); int[] intarray1 = new int[10]; int intarray2[] = new int[10]; String[] fruits = { "Äpple", "Päron", "Apelsin" }; // int intarray[10]; -- Ger kompileringsfel: ']' expected fruits = new String[] { "Ananas", "Banan" }; java.util.Arrays.sort(fruits); java.util.Arrays.fill(fruits, "Citron"); Hamster[] ha1 = { new Hamster("Adam"), new Hamster("Bertil"), new Hamster("Cesar") }; for (int i = 0; i < ha1.length; ++i) System.out.println("ha1[" + i + "]: '" + ha1[i] + "'"); Hamster[] ha2 = new Hamster[4]; ha2[0] = new Hamster("Anna"); ha2[1] = new Hamster("Beata"); ha2[2] = new Hamster("Cecilia"); ha2[3] = new Hamster("Dora"); try { ha2[4] = new Hamster("Eva"); } catch (ArrayIndexOutOfBoundsException e) { System.out.println("Undantag som fångades: '" + e + "'"); } for (int i = 0; i < ha2.length; ++i) System.out.println("ha2[" + i + "]: '" + ha2[i] + "'"); // ha2[2] = new Båt("Titanic"); -- Ger kompileringsfel: incompatible types // Man kan "ändra storlek" på en array genom att skapa en ny: System.out.println("ha2.length = " + ha2.length); ha2 = new Hamster[7]; System.out.println("ha2.length = " + ha2.length); // ArrayList är ett bra alternativ om man behöver en dynamisk array ArrayList båtar = new ArrayList(); Båt b1 = new Båt("Titanic"); Båt b2 = new Båt("Exxon Valdez"); Båt b3 = new Båt("Torrey Canyon"); båtar.add(b1); båtar.add(b2); båtar.add(b3); båtar.add(b1); båtar.add(b1); // En vanlig while-loop, till båtar.size() System.out.println("Båtarna (1):"); for (int i = 0; i < båtar.size(); ++i) System.out.println(" båtar[" + i + "]: " + båtar.get(i)); // En while-loop med en iterator System.out.println("Båtarna (2):"); Iterator i1 = båtar.iterator(); while (i1.hasNext()) System.out.println(" En båt: " + i1.next()); // Ett alternativt sätt att göra while-loopen med iteratorn System.out.println("Båtarna (3):"); for (Iterator i = båtar.iterator(); i.hasNext(); ) System.out.println(" En båt: " + i.next()); // Allra enklaste (?) sättet att göra while-loopen System.out.println("Båtarna (4):"); for (Båt i : båtar) { System.out.println(" En båt: " + i); } System.out.println("Båtarna (5):"); for (Iterator i = båtar.iterator(); i.hasNext(); ) { Båt b; b = i.next(); // Förr fick man göra; b = (Båt)i.next(); System.out.println(" En båt: " + b); } ArrayList saker = new ArrayList(); // Det där motsvarar det gamla // ArrayList saker = new ArrayList(); saker.add(b1); saker.add(b2); saker.add(b3); saker.add(b1); saker.add(b1); Hamster hasse = new Hamster("Hasse"); saker.add(hasse); // Inget fel -- "saker" innehåller Object, inte Båt! // Ojoj! Nu finns det en hamster bland båtarna i "saker". System.out.println("Sakerna (1):"); for (Iterator i = saker.iterator(); i.hasNext(); ) System.out.println(" En båt: " + i.next()); // Funkar, för toString finns i Object try { System.out.println("Sakerna (2):"); for (Iterator i = saker.iterator(); i.hasNext(); ) { Båt b; b = (Båt)i.next(); // Kommer att ge ClassCastException för hamstern Hasse System.out.println(" En båt: " + b); } } catch (ClassCastException e) { System.out.println("Undantag som fångades: '" + e + "'"); } // I Java kollar operatorn "==" om två referenser pekar på SAMMA objekt, // och metoden "equals" kollar om (programmeraren har bestämt att) de är LIKA. // h1 och h3 är SAMMA hamster. // h1 och h4 är är inte SAMMA, och inte heller LIKADANA (de har olika namn). // h1 och h2 är inte SAMMA hamster, men är de LIKA (de har samma namn)? // Nej, default-beteendet på equals är att objekt är LIKA bara om de är SAMMA objekt. Hamster h1 = new Hamster("Berra"); Hamster h2 = new Hamster("Berra"); Hamster h3 = h1; Hamster h4 = new Hamster("Osama"); System.out.println("h1 == h1: " + (h1 == h1)); System.out.println("h1 == h2: " + (h1 == h2)); System.out.println("h1 == h3: " + (h1 == h3)); System.out.println("h1 == h4: " + (h1 == h4)); System.out.println("h1.equals(h1): " + h1.equals(h1)); System.out.println("h1.equals(h2): " + h1.equals(h2)); System.out.println("h1.equals(h3): " + h1.equals(h3)); System.out.println("h1.equals(h4): " + h1.equals(h4)); // MEN! Man kan omdefiniera equals, så den returnerar sant för LIKA objekt och inte bara SAMMA! System.out.println("Hasses position (1): " + saker.indexOf(hasse)); System.out.println("Hasses position (2): " + saker.indexOf(new Hamster("Hasse"))); // Ta bort elementet på position fyra (dvs med index 3)! båtar.remove(4); // Ta bort (den första av förekomsterna av) Titanic båtar.remove(b1); System.out.println("Båtarna:"); for (Iterator i = båtar.iterator(); i.hasNext(); ) System.out.println(" En båt: " + i.next()); // En LinkedList är som en ArrayList, men med annorlunda prestanda LinkedList båtlista = new LinkedList(); for (Iterator i = båtar.iterator(); i.hasNext(); ) båtlista.add(i.next()); båtlista.addAll(båtar); // Alla på en gång! System.out.println("Båtarna i båtlistan:"); for (Iterator i = båtlista.iterator(); i.hasNext(); ) System.out.println(" En båt: " + i.next()); // En HashSet är en mängd, så den har inga dubletter HashSet båtmängd = new HashSet(); for (Iterator i = båtar.iterator(); i.hasNext(); ) båtmängd.add(i.next()); båtmängd.addAll(båtar); // Alla på en gång! System.out.println("Båtarna i båtmängden:"); for (Iterator i = båtmängd.iterator(); i.hasNext(); ) System.out.println(" En båt: " + i.next()); båtmängd.remove(b1); System.out.println("Båtarna i båtmängden, nu utan Titanic:"); for (Iterator i = båtmängd.iterator(); i.hasNext(); ) System.out.println(" En båt: " + i.next()); HashSet telefonnummermängd1 = new HashSet(); telefonnummermängd1.add(new Telefonnummer(116090)); telefonnummermängd1.add(new Telefonnummer(271010)); telefonnummermängd1.add(new Telefonnummer(271011)); telefonnummermängd1.add(new Telefonnummer(271012)); telefonnummermängd1.add(new Telefonnummer(111111)); telefonnummermängd1.add(new Telefonnummer(111111)); telefonnummermängd1.add(new Telefonnummer(111111)); System.out.println("Telefonnumren i telefonnummermängd 1:"); for (Iterator i = telefonnummermängd1.iterator(); i.hasNext(); ) System.out.println(" Ett telefonnummer: " + i.next()); System.out.println("Telefonnumren i telefonnummermängd 1, igen:"); for (Telefonnummer i : telefonnummermängd1) System.out.println(" Ett telefonnummer: " + i); // TreeSet kräver att objekten implementerar Comparable TreeSet telefonnummermängd2 = new TreeSet(); telefonnummermängd2.add(new Telefonnummer(116090)); telefonnummermängd2.add(new Telefonnummer(271010)); telefonnummermängd2.add(new Telefonnummer(271011)); telefonnummermängd2.add(new Telefonnummer(271012)); telefonnummermängd2.add(new Telefonnummer(111111)); telefonnummermängd2.add(new Telefonnummer(111111)); telefonnummermängd2.add(new Telefonnummer(111111)); System.out.println("Telefonnumren i telefonnummermängd 2:"); for (Iterator i = telefonnummermängd2.iterator(); i.hasNext(); ) System.out.println(" Ett telefonnummer: " + i.next()); System.out.println("Telefonnumren i telefonnummermängd 2, igen:"); for (Telefonnummer i : telefonnummermängd2) System.out.println(" Ett telefonnummer: " + i); // En "map" eller "mapping" kallas ibland "dictionary" eller "table". HashMap telefonbok1 = new HashMap(); telefonbok1.put("Anna", new Telefonnummer(116090)); telefonbok1.put("Bengt", new Telefonnummer(224000)); telefonbok1.put("Conny", new Telefonnummer(125566)); telefonbok1.put("Doris", new Telefonnummer(171045)); telefonbok1.put("Eberhart", new Telefonnummer(111111)); telefonbok1.put("Eberhart", new Telefonnummer(222222)); telefonbok1.put("Eberhart", new Telefonnummer(333333)); System.out.println("Conny har nummer " + telefonbok1.get("Conny")); System.out.println("Telefonbok 1:"); for (Iterator i = telefonbok1.keySet().iterator(); i.hasNext(); ) { String namn = i.next(); System.out.println(" " + namn + " har nummer " + telefonbok1.get(namn)); } System.out.println("Telefonbok 1, igen:"); for (String i : telefonbok1.keySet()) { System.out.println(" " + i + " har nummer " + telefonbok1.get(i)); } // TreeMap kräver att nycklarna implementerar Comparable (och det gör String) TreeMap telefonbok2 = new TreeMap(); telefonbok2.put("Anna", new Telefonnummer(116090)); telefonbok2.put("Bengt", new Telefonnummer(224000)); telefonbok2.put("Conny", new Telefonnummer(125566)); telefonbok2.put("Doris", new Telefonnummer(171045)); telefonbok2.put("Eberhart", new Telefonnummer(111111)); telefonbok2.put("Eberhart", new Telefonnummer(222222)); telefonbok2.put("Eberhart", new Telefonnummer(333333)); System.out.println("Telefonbok 2:"); for (Iterator i = telefonbok2.keySet().iterator(); i.hasNext(); ) { String namn = i.next(); System.out.println(" " + namn + " har nummer " + telefonbok2.get(namn)); } System.out.println("Telefonbok 2, igen:"); for (String i : telefonbok2.keySet()) { System.out.println(" " + i + " har nummer " + telefonbok2.get(i)); } // Man kan inte ha behållare (förutom inbyggda arrayer) av primitiva datatyper // ArrayList talen = new ArrayList(); // Men det finns boxade varianter av de typerna ArrayList talen = new ArrayList(); int tal1 = new Integer(1); talen.add(tal1); int tal2 = new Integer(1); talen.add(tal2); talen.add (new Integer(3)); // Auto-boxing int tal4 = 4; talen.add (tal4); talen.add(5); System.out.println("Talen:"); for (Integer i : talen) System.out.println(" Ett tal " + i); // Auto-unboxing System.out.println("Talen, igen:"); for (int i : talen) System.out.println(" Ett tal " + i); } // main } // Datatest