Snippet: How to test if a list of dates is sorted

List<Date> dates = Arrays.asList( new Date( 2L ), new Date( 3L ) );

boolean isSorted = new ArrayList<>( new TreeSet<>( dates ) ).equals( dates );

Über Christian Ullenboom

Ich bin Christian Ullenboom und Autor der Bücher ›Java ist auch eine Insel. Einführung, Ausbildung, Praxis‹ und ›Java SE 8 Standard-Bibliothek. Das Handbuch für Java-Entwickler‹. Seit 1997 berate ich Unternehmen im Einsatz von Java. Sun ernannte mich 2005 zum ›Java-Champion‹.

5 Gedanken zu „Snippet: How to test if a list of dates is sorted

  1. Hm. Besser wäre:

    boolean isSorted = com.google.common.collect.Ordering.natural().isOrdered(dates);

  2. Dieses Snippet ist nicht sehr … schön.

    1. Benutzt man ein Set. Was wenn man auch doppelte Elemente in seiner Liste hat?

    2. Wird bei dem Snippet eine neue Collection erzeugt, dann wird diese in eine ArrayList konvertiert, die wieder rum ein neues Array erzeugt.

    Sehr ineffizient. Es geht besser! Eine Möglichkeit ist der Vorschlag von ufkub, aber es geht noch besser. Wenn man eine Liste von Date Objekten nutzen möchte, dann kann man sich doch eine eigene Schreiben, die zusätzlich über eine Sortierungsmethode verfügt und intern ein sorted Flag verwaltet. Dabei muss man nur beachten, dass die „hinzufügenden“ Methoden das „isSorted“ Flag neu setzen müssen, alles andere wird an eine dahinter liegende List delegiert. Das ist viel effizienter. Hier ein Implementierungsvorschlag:

    public final class DateList implements List, Serializable, Cloneable {

    private static final long serialVersionUID = -65974214443173951L;

    public static DateList asList(Date… dates) {
    return new DateList(Arrays.asList(dates));
    }

    private final List backend;
    private boolean sorted;

    public DateList(List backend) {
    this.backend = backend;
    }

    public boolean isSorted() {
    return sorted;
    }

    public void sort() {
    Collections.sort(backend);
    sorted = true;
    }

    public void sort(Comparator c) {
    Collections.sort(backend, c);
    sorted = true;
    }

    // list interface methods

    @Override
    public boolean equals(Object obj) {
    return backend.equals(obj);
    }

    @Override
    public int hashCode() {
    return backend.hashCode();
    }

    @Override
    public String toString() {
    return backend.toString();
    }

    @Override
    public DateList clone() {
    return new DateList(new ArrayList(backend));
    }

    @Override
    public int size() {
    return backend.size();
    }

    @Override
    public boolean isEmpty() {
    return backend.isEmpty();
    }

    @Override
    public boolean contains(Object o) {
    return backend.contains(o);
    }

    @Override
    public Iterator iterator() {
    return listIterator();
    }

    @Override
    public Object[] toArray() {
    return backend.toArray();
    }

    @Override
    public T[] toArray(T[] a) {
    return backend.toArray(a);
    }

    @Override
    public boolean add(Date e) {
    add(size(), e);
    return true;
    }

    @Override
    public boolean remove(Object o) {
    return backend.remove(o);
    }

    @Override
    public boolean containsAll(Collection c) {
    return backend.containsAll(c);
    }

    @Override
    public boolean addAll(Collection c) {
    return addAll(size(), c);
    }

    @Override
    public boolean addAll(int index, Collection c) {
    boolean result = backend.addAll(index, c);
    sorted = false;
    return result;
    }

    @Override
    public boolean removeAll(Collection c) {
    return backend.removeAll(c);
    }

    @Override
    public boolean retainAll(Collection c) {
    return backend.retainAll(c);
    }

    @Override
    public void clear() {
    backend.clear();
    sorted = false;
    }

    @Override
    public Date get(int index) {
    return backend.get(index);
    }

    @Override
    public Date set(int index, Date element) {
    Date old = backend.set(index, element);
    sorted = false;
    return old;
    }

    @Override
    public void add(int index, Date element) {
    backend.add(index, element);
    sorted = false;
    }

    @Override
    public Date remove(int index) {
    return backend.remove(index);
    }

    @Override
    public int indexOf(Object o) {
    return backend.indexOf(o);
    }

    @Override
    public int lastIndexOf(Object o) {
    return backend.lastIndexOf(o);
    }

    @Override
    public ListIterator listIterator() {
    return listIterator(0);
    }

    @Override
    public ListIterator listIterator(int index) {
    return backend.listIterator(index);
    }

    @Override
    public List subList(int fromIndex, int toIndex) {
    return new DateList(backend.subList(fromIndex, toIndex));
    }
    }

  3. Argh Nr. 2: Habe vergessen bei den „remove“ methoden das „sorted“ flag zu setzen, falls die Liste leer wird. Eine leere Liste ist natürlich nicht sortiert. Aber das kann man ja in Handarbeit selbst ergänzen. 🙂

  4. Argh Nr. 3: die „listIterator(int)“ Methode müsste eigentlich eine eigene Implementierung zurück geben, da die remove(), set(Date) und add(Date) Methoden des ListIterators überschrieben werden müssen. Also:

    private void checkEmptynessAndSetFlag() {
    if (isEmpty()) {
    sorted = false;
    }
    }

    @Override
    public ListIterator listIterator(final int index) {
    return new ListIterator() {

    private final ListIterator iteratorBackend = backend.listIterator(index);

    @Override
    public boolean hasNext() {
    return iteratorBackend.hasNext();
    }

    @Override
    public Date next() {
    return iteratorBackend.next();
    }

    @Override
    public boolean hasPrevious() {
    return iteratorBackend.hasPrevious();
    }

    @Override
    public Date previous() {
    return iteratorBackend.previous();
    }

    @Override
    public int nextIndex() {
    return iteratorBackend.nextIndex();
    }

    @Override
    public int previousIndex() {
    return iteratorBackend.previousIndex();
    }

    @Override
    public void remove() {
    iteratorBackend.remove();
    checkEmptynessAndSetFlag();
    }

    @Override
    public void set(Date e) {
    iteratorBackend.set(e);
    sorted = false;
    }

    @Override
    public void add(Date e) {
    iteratorBackend.add(e);
    sorted = false;
    }
    };
    }

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.