Самый простой способ преобразования коллекции в массив?

Предположим, что a Collection<Foo>. Каков наилучший (самый короткий в LoC в текущем контексте) способ преобразования его в Foo[]? Любые известные библиотеки разрешены.

UPD: (еще один случай в этом разделе: оставляйте комментарии, если вы считаете нужным создать для него еще один поток): Как насчет преобразования Collection<Foo> в Bar[], где Bar имеет конструктор с 1 параметром типа Foo т.е. public Bar(Foo foo){ ... }?

Ответ 1

Где x - это коллекция:

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

Ответ 2

Альтернативное решение обновленного вопроса с использованием Java 8:

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

Ответ 3

Если вы используете его более одного раза или в цикле, вы можете определить константу

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[]{});

Ответ 4

Здесь окончательное решение для случая в разделе обновления (с помощью Коллекций Google):

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

Но ключевой подход здесь упоминался в двойном ответе (я забыл метод toArray).

Ответ 5

В JDK/11 альтернативным способом преобразования 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(), являются самыми быстрыми, вероятно, потому что они являются внутренними.

Он может избежать заполнения нулями только что выделенного массива, поскольку знает, что все содержимое массива будет перезаписано. Это верно независимо от того, как выглядит публичный API.

Реализация API в JDK гласит:

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

Реализация по умолчанию вызывает generator.apply(0) чтобы получить массив нулевой длины, а затем просто вызывает toArray(T[]). Это проходит через быстрый путь Arrays.copyOf(), поэтому, по сути, он такой же, как и toArray(new T[0]).


Примечание: - только то, что использование API должно руководствоваться обратной несовместимостью при использовании для кода с null значениями, например toArray(null) поскольку эти вызовы теперь будут неоднозначными из-за существующего toArray(T[] a) и не будут компилироваться,

Ответ 6

Для оригинала см. doublep ответ:

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);
}    

Ответ 7

Например, у вас есть коллекция ArrayList с элементами класса Student:

List stuList = new ArrayList();
Student s1 = new Student("Raju");
Student s2 = new Student("Harish");
stuList.add(s1);
stuList.add(s2);
//now you can convert this collection stuList to Array like this
Object[] stuArr = stuList.toArray();           // <----- toArray() function will convert collection to array