Самый простой способ преобразовать коллекцию в массив? - PullRequest
110 голосов
/ 21 июля 2010

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

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

Ответы [ 8 ]

238 голосов
/ 21 июля 2010

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

Foo[] foos = x.toArray(new Foo[x.size()]);
33 голосов
/ 19 ноября 2013

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

Bar[] result = foos.stream()
    .map(x -> new Bar(x))
    .toArray(size -> new Bar[size]);
10 голосов
/ 21 июля 2010

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

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[]{});
3 голосов
/ 26 июля 2018

В 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

Как объяснил @ Стюарт в списке рассылки (выделено мной), производительность по сути должна быть такой же, как и у существующего 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) и не будут компилироваться.

3 голосов
/ 21 июля 2010

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

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

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

2 голосов
/ 21 июля 2010

Для оригинального см. 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);
}    
1 голос
/ 28 мая 2019

Если вы используете Guava в своем проекте, вы можете использовать Iterables::toArray.

Foo[] foos = Iterables.toArray(x, Foo.class);
0 голосов
/ 17 января 2019

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

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...