8 Stimmen

Wie kann man N aufeinanderfolgende Elemente aus einer Sammlung zurückgeben?

Ich bin eine Sammlung von Objekten (einige Kontakt-Klasse in meinem Fall) übergeben und müssen eine Seite aus dieser Sammlung zurückgeben. Mein Code fühlt sich viel länger an, als er sein müsste. Vermisse ich einige Bibliotheken, die durchführen könnte, dass eleganter als Iteration über jedes Element ein zu einer Zeit, wie ich unten tun?

protected Collection<Contact> getPageOfContacts(
  Collection<Contact> contacts, int pageIndex, int pageSize) {
  if (pageIndex < 0 || pageSize <= 0
    || pageSize > contacts.size()) {
    return contacts;
  }
  int firstElement = pageIndex * pageSize;
  int lastElement = (pageIndex + 1) * pageSize - 1;
  Collection<Contact> pagedContacts = new ArrayList<Contact>();
  int index = -1;
  for (Contact contact : contacts) {
    index++;
    if (index < firstElement) {
      continue;
    }
    if (index > lastElement) {
      break;
    }
    pagedContacts.add(contact);
  }
  return pagedContacts;
}

13voto

Thomas Jung Punkte 31524

Sie könnten Guave verwenden Iterables.partition :

protected <T> Collection<T> getPageOfContacts(
        Collection<T> contacts, int pageIndex, int pageSize) {
    return Lists.newArrayList(
        Iterables.partition(contacts, pageSize)).get(pageIndex);
}

Eine komplexere Version erstellt nicht alle Seiten, um die richtige auszuwählen, sondern hält an, wenn die richtige Seite gefunden wird.

protected <T> Collection<T> getPageOfContacts(
        Collection<T> contacts, int pageIndex, int pageSize) {
    Iterator<List<T>> partitions = Iterators.partition(contacts.iterator(), pageSize);

    for(int page = 0; page<pageSize && partitions.hasNext(); page++){
        List<T> partition = partitions.next();
        if(page == pageIndex) return partition;
    }
    return Collections. <T> emptyList(); //or fail
}

Aktualisierung:

Vielen Dank an ColinD, der darauf hingewiesen hat:

Iterables.get(Iterables.partition(contacts, pageSize), pageIndex)

ist eine einfachere Implementierung.

6voto

ColinD Punkte 106101

Wenn Sie verlangen können, dass die auszulagernden Daten ein List können Sie eine Unterlistenansicht einer einzelnen Seite leicht erhalten, indem Sie Guave :

public <T> List<T> getPage(List<T> list, int pageIndex, int pageSize) {
  return Lists.partition(list, pageSize).get(pageIndex);
}

Dies erfordert kein Kopieren oder Iterieren (es werden Unterlistenansichten der ursprünglichen Liste verwendet) und behandelt eine endgültige Seite, die weniger als pageSize Elemente transparent zu machen.

Für eine beliebige Iterable o Collection dann würde ich das tun:

public <T> List<T> getPage(Iterable<T> iterable, int pageIndex, int pageSize) {
  return Iterables.get(Iterables.partition(iterable, pageSize), pageIndex);
}

Wenn Sie diese beiden Methoden bereitstellen, können Sie Objekte, von denen bekannt ist, dass sie Listen sind, zur Kompilierungszeit effizient behandeln und jede andere Art von Iterable so effizient wie möglich.

4voto

Ted Hopp Punkte 227177

Wenn Sie eine definierte Reihenfolge für Ihre Elemente wünschen, sollten Sie eine List , nicht ein collection . Der grundlegende Unterschied zwischen List y Collection ist das List hat eine feste Reihenfolge der Elemente. Sie definiert auch die sehr praktische Methode subList(int start, int end) die eine Unterliste erzeugt, die ein Alias der ursprünglichen Liste ist und nur die gewünschten Elemente enthält, ohne dass diese in eine neue Liste kopiert werden müssen.

1voto

Kevin Punkte 23989

Die Schnittstelle List bietet eine subList-Methode, die einen Start- und einen Endindex annimmt. Siehe http://download.oracle.com/javase/6/docs/api/java/util/List.html#subList(int,%20int. Die zurückgegebene Teilliste wird durch die ursprüngliche Liste unterstützt, so dass Sie wahrscheinlich etwas tun wollen wie

protected Collection<Contact> getPageOfContacts(...) {
    return new ArrayList<Contact>(original.subList(start,end));
}

0voto

Puce Punkte 36289
return new ArrayList<Contact>(new ArrayList<Contact>(contacts).subList(firstElement, lastElement));

Hinweis: Dies gibt die Unterliste exklusiv letztesElement

Anmerkung 2: Die Ergebnisse werden aus den von Kevin genannten Gründen in eine andere Liste kopiert.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X