를 생성하는 짧고 달콤한 방법이 있나요 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
.