Kleinsten und größten Wert einer ArrayList ermitteln

Manche Zahlen und Objekte speichere ich in einer ArrayList. Hier kann man relativ leicht Objekte hinzufügen (.add()) oder entfernen (.remove()). In diesem Artikel beschreibe ich, wie man den größten und den kleinsten Wert (Minumum und Maximum) einer ArrayList bestimmt.

Für eine ArrayList<Integer>

Am einfachsten ist die Bestimmung des Minimums und des Maximums bei einer Liste von Objekten mit einer natürlichen Reihenfolge, wie z.B. Integer-Zahlen. In dem Falle kann man die statischen Methoden max() und min() der Collections-Klasse verwenden. Je nachdem wie die Liste aufgebaut ist, kann es allerdings auch effizientere Wege geben (siehe Stackoverflow und Zparacha-Blog).

ArrayList<Integer> liste = new ArrayList<Integer>();
liste.add(100);
liste.add(200);
liste.add(110);
liste.add(99);
 
System.out.println("Maximum: " + Collections.max(liste));
System.out.println("Minimum: " + Collections.min(liste));

Vollständiges Beispiel:

package de.fenon.test;
 
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;
 
/**
 * Beispiel: Kleinsten und größten Wert in einer ArrayList finden.
 * @author fenon.de
 */
public final class HauptProgramm {
  /** Zahl der Messungen. */
  static final Integer STICHPROBE = 10;
  /** Maximalwert. */
  static final Integer MAXIMUM = 10;
  /** Seed des Zufallszahlen-Generators. */
  static final Integer SEED = 1234567891;
 
  /**
   * Privater Konstruktor.
   * Dadurch kann kein Objekt der Klasse "Hauptprogramm" erzeugt werden.
   */
  private HauptProgramm() {}
 
  /**
   * main()-Methode.
   * @param args - Parameter der Kommandozeile.
   */
  public static void main(final String[] args) {
    ArrayList<Integer> liste = new ArrayList<Integer>();
    // Erzeuge zufällige Messwerte
    Random generator = new Random(SEED);
    for (int i = 0; i < STICHPROBE; i++) {
      liste.add(generator.nextInt(MAXIMUM));
    }
    // Gib die Messwerte aus
    for (Integer element:liste) {
      System.out.println(element);
    }
    // Gib Kleinsten und Größten Wert aus
    System.out.println("Maximum: " + Collections.max(liste));
    System.out.println("Minimum: " + Collections.min(liste));
 
  } // ENDE: main()
 
} // ENDE: HauptProgramm

Für eine ArrayList mit komplexeren Objekten

Man kann allerdings auch den minimalen und maximalen Wert eigener/komplexerer Objekte bestimmen. Im folgenden Beispiel habe ich eine Liste von Objekten des eigenen Typs Website. Mit Hilfe eines Comparators (hier: VergleicheHits) kann festgelegt werden, wie die Objekte verglichen werden sollen. Im Beispiel werden die Website-Objekte dann anhand ihrer Zugriffzahlen verglichen.

Klasse: Website

package de.fenon.Website;
 
/**
 * Informationen über Webseite.
 * @author fenon.de
 */
public class Website {
  /** Zahl der Besucher der Website. */
  private Integer hits;
 
  /**
   * Konstruktor.
   * @param besuche - Zahl der Besucher.
   */
  public Website(final Integer besuche) {
    this.setHits(besuche);
  } // ENDE: Konstruktor
 
  /**
   * Gibt die Besucherzahl der Webseite aus.
   * @return Zahl der Besucher der Website.
   */
  public final Integer getHits() {
    return hits;
  } // ENDE: getHits()
 
  /**
   * Setze die Besucherzahl der Webseite.
   * @param besuche - Zahl der Besucher.
   */
  public final void setHits(final Integer besuche) {
    this.hits = besuche;
  } // ENDE: setHits()
 
} // ENDE: Website

Comparator: VergleicheHits

package de.fenon.Website;
 
import java.util.Comparator;
 
/**
 * Vergleiche Website-Objekte anhand ihrer Hits.
 * @author fenon.de
 */
public class VergleicheHits implements Comparator<Website> {
  /** Konstruktor. */
  public VergleicheHits() {}
 
  @Override
  public final int compare(final Website a, final Website b) {
    if (a.getHits() < b.getHits()) {
      return -1;
    } else if (a.getHits().equals(b.getHits())) {
      return 0;
    } else {
      return 1;
    }
  } // ENDE: compare()
 
} // ENDE: VergleicheHits

Das Beispiel

package de.fenon.test;
 
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;
 
import de.fenon.Website.VergleicheHits;
import de.fenon.Website.Website;
 
/**
 * Beispiel: Kleinsten und größten Wert in einer Liste finden.
 * @author fenon.de
 */
public final class HauptProgramm {
  /** Zahl der Messungen. */
  static final Integer STICHPROBE = 10;
  /** Maximalwert. */
  static final Integer MAXIMUM = 10;
  /** Seed des Zufallszahlen-Generators. */
  static final Integer SEED = 1234567891;
 
  /**
   * Privater Konstruktor.
   * Dadurch kann kein Objekt der Klasse "Hauptprogramm" erzeugt werden.
   */
  private HauptProgramm() {}
 
  /**
   * main()-Methode.
   * @param args - Parameter der Kommandozeile.
   */
  public static void main(final String[] args) {
    ArrayList<Website> seiten = new ArrayList<Website>();
    // Erzeuge zufällige Messwerte
    Random generator = new Random(SEED);
    for (int i = 0; i < STICHPROBE; i++) {
      seiten.add(new Website(generator.nextInt(MAXIMUM)));
    }
    // Gib die Messwerte aus
    for (Website element:seiten) {
      System.out.println("Hits: " + element.getHits());
    }
    // Gib Kleinsten und Größten Wert aus.
    // Mit einem anderen Getter könnte man z.B. den Namen der Website ausgeben.
    System.out.println(
      "Maximum: "
      + Collections.max(seiten, new VergleicheHits()).getHits()
      );
    System.out.println(
      "Minimum: "
      + Collections.min(seiten, new VergleicheHits()).getHits()
      );
  } // ENDE: main()
 
} // ENDE: HauptProgramm

Eine Liste zu einem data.frame konvertieren in R

Manchmal liegen in R Daten in Form einer Liste vor (z.B. die Ausgabe der Funktion hist()). In einer Liste können Daten enthalten sein, die eine unterschiedliche Länge haben. Im Falle von hist() sind z.B. Arrays unterschiedlicher Länge gemeinsam mit einfachen Variablen in einer Liste kombiniert.

Für weitere Analysen kann es jedeoch hilfreich sein, die gleich langen Teile in einen separaten data.frame auszulagern. Dann kann z.B. mit Hilfe der Funktion subset() relativ einfach Bereiche aus den Daten herausfiltern.

In R gibt es keine vorgefertigte Funktion, die direkt Daten vom Typ list in Daten vom Typ data.frame konvertieren kann. Das liegt daran, dass in einem data.frame alle enthaltenen Variablen (in der Regel Arrays) die gleiche Länge haben müssen. Unsere Entscheidung, welche Variablen aus der Liste in den data.frame übernommen werden sollen, müssen wir R mitteilen.

Das folgende Beispiel zeigt, wie man das sehr einfach bewerkstelligen kann:

1
2
3
4
5
6
7
8
# Liste mit Arrays ("x", "y", "sd") und einer Variablen ("name")
liste = list(x=c(1:5), y=c(11:15), sd=c(0,1,2,0,0), name="Meine Liste")
 
# data.frame ("df") erzeugen mit den Variablen "x", "y" und "sd"
df = with(data=liste, expr=data.frame(x, y))
 
# Struktur des data.frames ausgeben
str(df)
'data.frame':	5 obs. of  3 variables:
 $ x : int  1 2 3 4 5
 $ y : int  11 12 13 14 15
 $ sd: num  0 1 2 0 0

Im Anschluss kann man sehr einfach nur bestimmte Teile des data.frame ausgeben lassen.
Das kann man z.B. direkt über den Index (df[zeile, spalte]) oder über die Funktion subset() machen.

1
2
3
4
5
6
7
8
9
# Nur das zweite und vierte Element (Zeile) anzeigen
df[c(2,4),]
 
# Nur die Elemente (Zeilen) anzeigen, bei denen x>2 ist
df[(df$x>2),]
 
# Nur die Elemente (Zeilen) der Variablen (Spalten) x und y ausgeben,
# bei denen sd<1 und x>2 ist
subset(df, subset=(x>2 & sd<1), select=c(x,y))