Gibt es eine kurze und süße Möglichkeit, ein List<Integer>
oder vielleicht ein Integer[]
oder int[]
mit sequentiellen Werten von einem start
Wert zu einem end
Wert zu generieren ?
Das heißt, etwas kürzer als, aber gleich 1 der folgenden:
void List<Integer> makeSequence(int begin, int end) {
List<Integer> ret = new ArrayList<>(end - begin + 1);
for (int i=begin; i<=end; i++) {
ret.add(i);
}
return ret;
}
Die Verwendung von Guave ist in Ordnung.
Aktualisieren:
Performance-Analyse
Da diese Frage mehrere gute Antworten erhalten hat, sowohl mit nativem Java 8 als auch mit Bibliotheken von Drittanbietern, dachte ich, ich würde die Leistung aller Lösungen testen.
Der erste Test testet einfach das Erstellen einer Liste von 10 Elementen [1..10]
mit den folgenden Methoden:
- classicArrayList : Der oben in meiner Frage angegebene Code (und im Wesentlichen der gleiche wie die Antwort von adarshr).
- eclipseCollections : Der in Donalds Antwort unten angegebene Code unter Verwendung von Eclipse Collections 8.0.
- guavaRange : Der Code, der in der Antwort von daveb unten angegeben ist. Technisch gesehen erzeugt dies kein,
List<Integer>
sondern einContiguousSet<Integer>
- aber da esIterable<Integer>
in der richtigen Reihenfolge implementiert wird, funktioniert es hauptsächlich für meine Zwecke. - intStreamRange : Der Code in der folgenden Antwort von Vladimir , der verwendet
IntStream.rangeClosed()
- der in Java 8 eingeführt wurde. - streamIterate : Der in der folgenden Antwort von Catalin angegebene Code, der auch die
IntStream
in Java 8 eingeführten Funktionen verwendet .
Hier sind die Ergebnisse in Kilobetrieben pro Sekunde (höhere Zahlen sind besser) für alle oben genannten mit Listen der Größe 10:
... und noch einmal für Listen der Größe 10.000:
Das letzte Diagramm ist korrekt - andere Lösungen als Eclipse und Guava sind zu langsam, um überhaupt einen einzelnen Pixelbalken zu erhalten! Die schnellen Lösungen sind 10.000 bis 20.000 Mal schneller als die anderen.
Was hier natürlich vor sich geht, ist, dass die Guaven- und Eclipse-Lösungen tatsächlich keine 10.000-Elemente-Liste materialisieren - sie sind einfach Wrapper fester Größe um den Start- und Endpunkt. Jedes Element wird nach Bedarf während der Iteration erstellt. Da wir in diesem Test nicht wirklich iterieren, werden die Kosten zurückgestellt. Alle anderen Lösungen materialisieren tatsächlich die vollständige Liste im Speicher und zahlen einen hohen Preis für einen Benchmark nur für die Erstellung.
Lassen Sie uns etwas Realistischeres tun und auch alle ganzen Zahlen durchlaufen und summieren. Bei der IntStream.rangeClosed
Variante sieht der Benchmark also so aus:
@Benchmark
public int intStreamRange() {
List<Integer> ret = IntStream.rangeClosed(begin, end).boxed().collect(Collectors.toList());
int total = 0;
for (int i : ret) {
total += i;
}
return total;
}
Hier ändern sich die Bilder stark, obwohl die nicht materialisierenden Lösungen immer noch die schnellsten sind. Hier ist Länge = 10:
... und Länge = 10.000:
Die lange Iteration über viele Elemente gleicht die Dinge viel aus, aber Eclipse und Guave bleiben selbst beim 10.000-Elemente-Test mehr als doppelt so schnell.
Wenn Sie also wirklich eine List<Integer>
Eclipse-Sammlung wünschen , scheint dies die beste Wahl zu sein. Wenn Sie Streams jedoch nativer verwenden (z. B. .boxed()
die primitive Domäne vergessen und reduzieren), werden Sie wahrscheinlich schneller als alle diese sein Varianten.
1 Möglicherweise mit Ausnahme der Fehlerbehandlung, z. B. wenn end
< begin
oder wenn die Größe einige Implementierungs- oder JVM-Grenzwerte überschreitet (z. B. Arrays größer als 2^31-1
.
quelle
Antworten:
Mit Java 8 ist es so einfach, dass es nicht einmal mehr eine separate Methode benötigt:
quelle
Nun, dieser eine Liner könnte sich qualifizieren (verwendet Guava Ranges )
Dies schafft keine
List<Integer>
,ContiguousSet
bietet aber fast die gleiche Funktionalität, insbesondere die Implementierung,Iterable<Integer>
die dieforeach
Implementierung auf die gleiche Weise wie ermöglichtList<Integer>
.In älteren Versionen (irgendwo vor Guava 14) können Sie Folgendes verwenden:
Beide produzieren:
quelle
asList()
es sei denn, Sie benötigen wirklich einList
... dasContiguousSet
vonasSet
ist leicht (es benötigt nur den Bereich und die Domäne), sondernasList()
erstellt eine Liste, in der (derzeit) tatsächlich alle Elemente im Speicher gespeichert sind.Range
existiert aber nichtRanges
und sie haben dieasSet
Methode abgeschafft. In meiner älteren VersionasSet
ist veraltet und es scheint, dass sie es entfernt haben. Bereiche sollen anscheinend nur für zusammenhängende Sammlungen verwendet werden, und sie haben sie durchgesetzt, obwohl ich diese Lösung liebe.Die folgende einzeilige Java 8-Version generiert [1, 2, 3 ... 10]. Das erste Argument von
iterate
ist das erste nr in der Sequenz, und das erste Argument vonlimit
ist die letzte Zahl.quelle
Sie können die
Interval
Klasse aus Eclipse-Sammlungen verwenden .Die
Interval
Klasse ist faul, speichert also nicht alle Werte.Ihre Methode kann wie folgt implementiert werden:
Wenn Sie Boxing Ints als Ganzzahlen vermeiden möchten, aber dennoch eine Listenstruktur als Ergebnis wünschen, können Sie diese
IntList
mitIntInterval
aus Eclipse-Sammlungen verwenden.IntList
hat die Methodensum()
,min()
,minIfEmpty()
,max()
,maxIfEmpty()
,average()
undmedian()
an der Schnittstelle zur Verfügung.Update aus Gründen der Übersichtlichkeit: 27.11.2017
An
Interval
ist aList<Integer>
, aber es ist faul und unveränderlich. Es ist äußerst nützlich, um Testdaten zu generieren, insbesondere wenn Sie viel mit Sammlungen zu tun haben. Wenn Sie möchten , können Sie ein Intervall auf eine leicht zu kopierenList
,Set
oderBag
wie folgt:Ein
IntInterval
ist ein,ImmutableIntList
das sich erstrecktIntList
. Es hat auch Konvertermethoden.An
Interval
und anIntInterval
haben nicht den gleichenequals
Vertrag.Update für Eclipse-Sammlungen 9.0
Sie können jetzt primitive Sammlungen aus primitiven Streams erstellen. Es gibt
withAll
undofAll
Methoden je nach Ihren Vorlieben. Wenn Sie neugierig sind, erkläre ich, warum wir beide hier haben . Diese Methoden existieren für veränderbare und unveränderliche Int / Long / Double-Listen, Sets, Bags und Stacks.Hinweis: Ich bin ein Committer für Eclipse-Sammlungen
quelle
Dies ist die kürzeste Zeit, die ich mit Core Java bekommen kann.
quelle
for(int i = begin; i <= end; ret.add(i++));
:)ret.add(i)
Teils in das for-Schleifeninkrement dies "kürzer" macht. Ich denke nach dieser Logik wäre es kürzer, wenn ich alles in eine ZeileSie könnten Guavenbereiche verwenden
Sie können eine erhalten,
SortedSet
indem Siequelle
Dies ist die kürzeste, die ich finden konnte.
Listenversion
Array-Version
quelle
Dieser könnte für Sie arbeiten ....
quelle