를 생성하는 짧고 달콤한 방법이 있나요 List<Integer>
, 또는 아마도 Integer[]
또는 int[]
일부에서 순차 값, start
가치 end
가치인가?
즉, 다음보다 짧지 만 1에 해당합니다.
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;
}
구아바 사용은 괜찮습니다.
최신 정보:
성능 분석
이 질문은 네이티브 Java 8 및 타사 라이브러리를 사용하여 몇 가지 좋은 답변을 받았으므로 모든 솔루션의 성능을 테스트 할 것이라고 생각했습니다.
첫 번째 테스트 [1..10]
는 다음 방법을 사용하여 10 개의 요소 목록을 만드는 것을 테스트 합니다.
- classicArrayList : 내 질문에서 위에 주어진 코드 (그리고 본질적으로 adarshr의 대답과 동일).
- eclipseCollections : Eclipse Collections 8.0을 사용하여 아래 Donald의 답변에 제공된 코드 .
- guavaRange : 아래 daveb 의 답변에 제공된 코드 . 기술적으로 이것은 a를 생성하는
List<Integer>
것이 아니라 순서대로ContiguousSet<Integer>
구현Iterable<Integer>
하기 때문에 대부분 내 목적에 적합합니다. - intStreamRange : 아래 Vladimir의 답변에 제공된 코드
IntStream.rangeClosed()
로 Java 8에서 도입 된-를 사용합니다 . - streamIterate : Java 8에 도입 된 기능 을 사용하는 아래 Catalin의 답변에 제공된 코드
IntStream
입니다.
다음은 목록 크기가 10 인 위의 모든 항목에 대한 초당 킬로 작업 (숫자가 클수록 좋음)의 결과입니다.
… 그리고 다시 한번 크기가 10,000 인 목록 :
마지막 차트는 정확합니다. Eclipse 및 Guava 이외의 솔루션은 너무 느려 단일 픽셀 막대를 얻을 수도 없습니다! 빠른 솔루션은 나머지 솔루션보다 10,000 ~ 20,000 배 빠릅니다.
물론 여기서 진행되는 것은 구아바와 이클립스 솔루션이 실제로 10,000 개의 요소 목록을 구체화하지 않는다는 것입니다. 단순히 시작과 끝점을 둘러싼 고정 된 크기의 래퍼입니다. 각 요소는 반복 중에 필요에 따라 생성됩니다. 이 테스트에서는 실제로 반복하지 않기 때문에 비용이 지연됩니다. 다른 모든 솔루션은 실제로 전체 목록을 메모리에 구체화하고 생성 전용 벤치 마크에서 많은 비용을 지불합니다.
좀 더 현실적인 작업을하고 모든 정수를 반복하여 합산 해 봅시다. 따라서 IntStream.rangeClosed
변형 의 경우 벤치 마크는 다음과 같습니다.
@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;
}
여기서 비 물질화 솔루션이 여전히 가장 빠르지 만 그림은 많이 변경됩니다. 길이 = 10입니다.
… 및 길이 = 10,000 :
많은 요소에 대한 긴 반복은 많은 것을 고르게하지만 일식과 구아바는 10,000 개의 요소 테스트에서도 두 배 이상 빠르게 유지됩니다.
따라서 정말로List<Integer>
, eclipse 컬렉션을 원한다면 이클립스 컬렉션이 최선의 선택 인 것처럼 보이지만 물론 더 네이티브 방식으로 스트림을 사용한다면 (예 : .boxed()
원시 도메인을 잊어 버리고 축소하는 것) 아마이 모든 것보다 더 빨리 끝날 것입니다. 변형.
1 오류 처리 (예 : end
< begin
인 경우) 또는 크기가 일부 구현 또는 JVM 제한을 초과하는 경우 (예 : 2^31-1
.
답변
Java 8을 사용하면 매우 간단하므로 더 이상 별도의 메서드가 필요하지 않습니다.
List<Integer> range = IntStream.rangeClosed(start, end)
.boxed().collect(Collectors.toList());
답변
글쎄,이 라이너는 자격이 될 수 있습니다 ( 구아바 범위 사용 )
ContiguousSet<Integer> integerList = ContiguousSet.create(Range.closedOpen(0, 10), DiscreteDomain.integers());
System.out.println(integerList);
이것은을 만들지 않습니다 List<Integer>
,하지만 ContiguousSet
구현 특히, 거의 같은 기능을 제공 Iterable<Integer>
할 수있는 foreach
같은 방법으로 구현 List<Integer>
.
구아바 14 이전 버전에서는 다음을 사용할 수 있습니다.
ImmutableList<Integer> integerList = Ranges.closedOpen(0, 10).asSet(DiscreteDomains.integers()).asList();
System.out.println(integerList);
둘 다 생산 :
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
답변
다음 한 줄짜리 Java 8 버전은 [1, 2, 3 … 10]을 생성합니다. 의 첫 번째 인수 iterate
는 시퀀스의 첫 번째 nr이고 첫 번째 인수 limit
는 마지막 숫자입니다.
List<Integer> numbers = Stream.iterate(1, n -> n + 1)
.limit(10)
.collect(Collectors.toList());
답변
Eclipse Collections 의 Interval
클래스를 사용할 수 있습니다 .
List<Integer> range = Interval.oneTo(10);
range.forEach(System.out::print); // prints 12345678910
Interval
클래스는 게으른, 그래서 모든 값을 저장하지 않습니다.
LazyIterable<Integer> range = Interval.oneTo(10);
System.out.println(range.makeString(",")); // prints 1,2,3,4,5,6,7,8,9,10
귀하의 방법은 다음과 같이 구현할 수 있습니다.
public List<Integer> makeSequence(int begin, int end) {
return Interval.fromTo(begin, end);
}
int를 Integers로 사용하는 것을 피하고 싶지만 결과적으로 목록 구조를 원하는 경우 Eclipse Collections에서 IntList
with IntInterval
를 사용할 수 있습니다 .
public IntList makeSequence(int begin, int end) {
return IntInterval.fromTo(begin, end);
}
IntList
이 방법 sum()
, min()
, minIfEmpty()
, max()
, maxIfEmpty()
, average()
및 median()
인터페이스에 사용할 수 있습니다.
명확성을위한 업데이트 : 2017 년 11 월 27 일
An Interval
은 List<Integer>
이지만 게으르고 변경할 수 없습니다. 특히 컬렉션을 많이 다루는 경우 테스트 데이터를 생성하는 데 매우 유용합니다. 당신이 원하는 경우에 당신은에 간격을 복사 쉽게 할 수 있습니다 List
, Set
또는 Bag
같은 다음과 같습니다 :
Interval integers = Interval.oneTo(10);
Set<Integer> set = integers.toSet();
List<Integer> list = integers.toList();
Bag<Integer> bag = integers.toBag();
는 IntInterval
이다 ImmutableIntList
연장 IntList
. 또한 변환기 방법이 있습니다.
IntInterval ints = IntInterval.oneTo(10);
IntSet set = ints.toSet();
IntList list = ints.toList();
IntBag bag = ints.toBag();
An Interval
과 an IntInterval
은 동일한 equals
계약을 가지고 있지 않습니다 .
이제 기본 스트림에서 기본 컬렉션을 만들 수 있습니다. 있다 withAll
및 ofAll
환경 설정에 따라 방법. 궁금한 점이 있으면 여기에 둘 다있는 이유를 설명 합니다 . 이러한 메소드는 변경 가능하고 변경 불가능한 Int / Long / Double 목록, 세트, 백 및 스택에 존재합니다.
Assert.assertEquals(
IntInterval.oneTo(10),
IntLists.mutable.withAll(IntStream.rangeClosed(1, 10)));
Assert.assertEquals(
IntInterval.oneTo(10),
IntLists.immutable.withAll(IntStream.rangeClosed(1, 10)));
참고 : 저는 Eclipse 컬렉션 커미터입니다.
답변
이것은 Core Java를 사용할 수있는 가장 짧은 것입니다.
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;
}
답변
Guava Ranges를 사용할 수 있습니다.
다음 SortedSet
을 사용하여 얻을 수 있습니다.
ImmutableSortedSet<Integer> set = Ranges.open(1, 5).asSet(DiscreteDomains.integers());
// set contains [2, 3, 4]
답변
이것은 내가 찾을 수있는 가장 짧은 것입니다.
목록 버전
public List<Integer> makeSequence(int begin, int end)
{
List<Integer> ret = new ArrayList<Integer>(++end - begin);
for (; begin < end; )
ret.add(begin++);
return ret;
}
어레이 버전
public int[] makeSequence(int begin, int end)
{
if(end < begin)
return null;
int[] ret = new int[++end - begin];
for (int i=0; begin < end; )
ret[i++] = begin++;
return ret;
}