Jak wygenerować listę lub tablicę kolejnych liczb całkowitych w Javie?

Czy istnieje krótki i słodki sposób na wygenerowanieList<Integer>lub możeInteger[] lubint[], z kolejnymi wartościami z niektórychstart wartość doend wartość?

To znaczy, coś krótszego niż, ale równoważnego1 następujące:

<code>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;  
}
</code>

Korzystanie z guawy jest w porządku.

Aktualizacja:

Analiza wydajności

Ponieważ to pytanie otrzymało kilka dobrych odpowiedzi, zarówno przy użyciu rodzimych bibliotek Java 8, jak i bibliotek innych firm, pomyślałem, że przetestuję wydajność wszystkich rozwiązań.

Pierwszy test po prostu testuje tworzenie listy 10 elementów[1..10] przy użyciu następujących metod:

classicArrayList: kod podany powyżej w moim pytaniu (i zasadniczo taki sam jak odpowiedź adarshra).eclipseCollections: kod podany wOdpowiedź Donalda poniżej za pomocą Eclipse Collections 8.0.guavaRange: kod podany wodpowiedź daveba poniżej. Technicznie nie tworzy toList<Integer> ale raczejContiguousSet<Integer> - ale ponieważ się wdrażaIterable<Integer> w porządku, głównie działa dla moich celów.intStreamRange: kod podany wOdpowiedź Vladimira poniżej, który używaIntStream.rangeClosed() - który został wprowadzony w Javie 8.streamIterate: kod podany wOdpowiedź Catalina poniżej, który również używaIntStream funkcjonalność wprowadzona w Javie 8.

Oto wyniki w kilo-operacjach na sekundę (lepsze liczby są lepsze), dla wszystkich powyższych z listami o rozmiarze 10:

... i ponownie dla list o rozmiarze 10 000:

Ta ostatnia tabela jest poprawna - rozwiązania inne niż Eclipse i Guava są zbyt wolne, aby uzyskać pojedynczy pasek pikseli! Szybkie rozwiązania to 10 000 do 20 000czasy szybciej niż reszta.

To, co dzieje się tutaj, jest oczywiście takie, że rozwiązania guawy i eclipse w rzeczywistości nie urzeczywistniają żadnej listy 10 000 elementów - są po prostu opakowaniami o stałym rozmiarze wokół punktów początkowych i końcowych. Każdy element jest tworzony w razie potrzeby podczas iteracji. Ponieważ w tym teście nie wykonujemy iteracji, koszt jest odroczony. Wszystkie inne rozwiązania faktycznie urzeczywistniają pełną listę w pamięci i płacą wysoką cenę w benchmarku tylko do tworzenia.

Zróbmy coś bardziej realistycznego, a także iterujemy wszystkie liczby całkowite, sumując je. Więc w przypadkuIntStream.rangeClosed wariant, benchmark wygląda tak:

<code>@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;  
}
</code>

Tutaj zdjęcia bardzo się zmieniają, chociaż rozwiązania niematerialne są wciąż najszybsze. Oto długość = 10:

... i długość = 10 000:

Długa iteracja wielu elementów bardzo wyrównuje sytuację, ale zaćmienie i guawa pozostają ponad dwukrotnie szybsze nawet w teście z 10 000 elementów.

Więc jeśli tynaprawdę chcęList<Integer>kolekcje eclipse wydają się najlepszym wyborem - ale oczywiście, jeśli używasz strumieni w sposób bardziej natywny (np. zapominając.boxed() i dokonując redukcji w prymitywnej domenie) prawdopodobnie skończysz szybciej niż wszystkie te warianty.

1 Być może z wyjątkiem obsługi błędów, np. Jeśliend < beginlub jeśli rozmiar przekracza niektóre ograniczenia implementacji lub JVM (np. tablice większe niż2^31-1.

questionAnswers(8)

yourAnswerToTheQuestion