[java] 컬렉션을 배열로 변환하는 가장 쉬운 방법은 무엇입니까?

우리가 Collection<Foo>. 그것을 변환하는 가장 좋은 (현재 컨텍스트에서 LoC에서 가장 짧은) 방법은 Foo[]무엇입니까? 어떤은 잘 알려진 라이브러리를 사용할 수 있습니다.

UPD :; : 어떤 변화에 대해 (이 부분에서 또 하나의 사례 휴가 코멘트 당신은 그것의 가치는 그것을 위해 다른 스레드를 만들 생각하는 경우) Collection<Foo>Bar[]어디 Bar유형의 한 매개 변수를 생성자가 Foopublic Bar(Foo foo){ ... }?



답변

x컬렉션은 어디에 있습니까?

Foo[] foos = x.toArray(new Foo[x.size()]);


답변

Java 8을 사용하여 업데이트 된 질문에 대한 대체 솔루션 :

Bar[] result = foos.stream()
    .map(x -> new Bar(x))
    .toArray(size -> new Bar[size]);


답변

두 번 이상 사용하거나 루프에서 사용하는 경우 상수를 정의 할 수 있습니다.

public static final Foo[] FOO = new Foo[]{};

다음과 같은 변환을 수행하십시오.

Foo[] foos = fooCollection.toArray(FOO);

toArray메서드는 빈 배열을 사용하여 대상 배열의 올바른 유형을 결정하고 새 배열을 만듭니다.


업데이트에 대한 제 제안은 다음과 같습니다.

Collection<Foo> foos = new ArrayList<Foo>();
Collection<Bar> temp = new ArrayList<Bar>();
for (Foo foo:foos)
    temp.add(new Bar(foo));
Bar[] bars = temp.toArray(new Bar[]{});


답변

JDK / 11에서 a Collection<Foo>를 로 변환하는 다른 방법은 다음 Foo[]Collection.toArray(IntFunction<T[]> generator)같이 사용하는 것입니다.

Foo[] foos = fooCollection.toArray(new Foo[0]); // before JDK 11
Foo[] updatedFoos = fooCollection.toArray(Foo[]::new); // after JDK 11

에 의해 설명으로 메일 링리스트에 @Stuart (강조 광산), 이것의 성능은 기본적으로 기존의 것과 동일해야합니다 Collection.toArray(new T[0])

결론적으로 그 구현이 사용하는 것입니다 Arrays.copyOf() 아마 때문에 가장 빠르다 는 고유이다 .

전체 배열 내용을 덮어 쓸 것임을 알고 있기 때문에 새로 할당 된 배열을 0으로 채우는 것을 방지 할 수 있습니다. 이는 공개 API가 어떻게 생겼는지에 관계없이 사실입니다.

JDK 내의 API 구현은 다음과 같습니다.

default <T> T[] toArray(IntFunction<T[]> generator) {
    return toArray(generator.apply(0));
}

기본 구현은 generator.apply(0)길이가 0 인 배열을 가져 오기 위해 호출 한 다음 단순히 toArray(T[]). 이것은 Arrays.copyOf()
빠른 경로 를 통과 하므로 기본적으로 toArray(new T[0]).


참고 :-값이있는코드에 사용할 때API 사용은 이전 버전 과의 비 호환성 과 함께 안내되어야null합니다. 예를 들어toArray(null)이러한 호출은 기존 때문에 모호toArray(T[] a)하고 컴파일에 실패하기때문입니다.


답변

프로젝트에서 Guava를 사용하는 경우 Iterables::toArray.

Foo[] foos = Iterables.toArray(x, Foo.class);


답변

원본의 경우 이중 답변을 참조하십시오 .

Foo[] a = x.toArray(new Foo[x.size()]);

업데이트에 관해서 :

int i = 0;
Bar[] bars = new Bar[fooCollection.size()];
for( Foo foo : fooCollection ) { // where fooCollection is Collection<Foo>
    bars[i++] = new Bar(foo);
}    


답변

다음은 업데이트 섹션의 사례에 대한 최종 솔루션입니다 (Google 컬렉션의 도움으로).

Collections2.transform (fooCollection, new Function<Foo, Bar>() {
    public Bar apply (Foo foo) {
        return new Bar (foo);
    }
}).toArray (new Bar[fooCollection.size()]);

그러나 여기서 핵심 접근 방식 은 doublep의 답변 에서 언급되었습니다 (나는 toArray방법을 잊었습니다 ).