2010-12-21 7 views
4

Die Java Collections Klasse hat die folgende Methode:Guave-Bibliotheken: Liste mit n Instanzen

static <T> List<T> nCopies(int n, T o) 

Ich brauche ein ähnliches Verfahren, aber etwas mehr Generika, die n Instanzen einer bestimmten Klasse zur Verfügung stellt. Etwas wie:

static <T> List<T> nInstances(int n, Supplier<T> supplier) 

Insbesondere wenn supplier ist Supplier.ofInstance(o), bekommen wir das gleiche Verhalten wie die nCopies() Methode. Gibt es irgendwo in der Guava API eine solche Methode?

Vielen Dank.

Antwort

2

Nein, aber es ist einfach genug, um zu implementieren:

public static <T> List<T> nInstances(int n, Supplier<T> supplier){ 
    List<T> list = Lists.newArrayListWithCapacity(n); 
    for(int i = 0; i < n; i++){ 
     list.add(supplier.get()); 
    } 
    return list; 
} 
+0

Ich glaube nicht, dass kann wirklich als äquivalent zu 'Collections.nCopies' betrachtet werden, da das Unterscheidende daran ist, dass die' List', die es zurückgibt, minimalen Speicher verwendet (nur ein int und eine Referenz). Dadurch werden alle vom Lieferanten zurückgegebenen Werte in eine 'ArrayList' geschrieben. – ColinD

+0

Sicher, es ist einfach genug. In der Tat habe ich bereits genau das umgesetzt, was Sie vorschlagen. –

+0

@ColinD nein, es ist nicht gleichwertig (und es ist definitiv nicht Guava-würdig). Aber es tut, was das OP wollte –

4

Nein gibt es nicht, und jedes gleichwertige Konstrukt (das speichert nur die Int n und der Lieferant und ruft den Lieferanten für jede get) scheint eine schreckliche Idee. Das heißt, anscheinend möchten Sie nur n Objekte von einem Supplier lesen und sie in einer Liste speichern. In diesem Fall ist Seans Antwort wahrscheinlich die beste.

Just for fun aber hier ist eine andere Art und Weise könnte man eine ImmutableList der Größe n erstellen, indem Sie eine Supplier n-mal aufrufen (transform, limit und cycle alle von Iterables):

public static <T> ImmutableList<T> nInstances(int n, Supplier<T> supplier) { 
    return ImmutableList.copyOf(transform(
     limit(cycle(supplier), n), Suppliers.<T>supplierFunction())); 
} 

Ich uh ... wouldn Ich empfehle dies jedoch über eine einfache Schleifenimplementierung (hauptsächlich aus Gründen der Lesbarkeit).

+0

Hier ist eine andere Spaß eine Linie Ansatz: Transformation (Grenze (Zyklus (1), Copycount), Functions.forSupplier (Lieferant)) – Spina

2

Wie viele andere Idiome, Java 8 liefert schließlich mit einer kurzen und süßen Version, die keine externen Bibliotheken benötigt. Sie können dies jetzt mit Streams.generate(Supplier<T> s) tun. Zum Beispiel für n Instanzen Foo:

Streams.generate(Foo::new).limit(n)... 

würden Sie diese Zeile aus auf verschiedene Weise beenden, je nachdem wie wollten Sie Ihre Liste erstellen. Zum Beispiel für eine ImmutableList:

ImmutableList.copyOf(Streams.generate(Foo::new).limit(n).iterator());