The easiest way to transform collection to array?

柔情痞子 提交于 2019-11-27 00:15:45
doublep

Where x is the collection:

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

Alternative solution to the updated question using Java 8:

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

If you use it more than once or in a loop, you could define a constant

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

and do the conversion it like

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

The toArray method will take the empty array to determine the correct type of the target array and create a new array for you.


Here's my proposal for the update:

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

Here's the final solution for the case in update section (with the help of Google Collections):

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

But, the key approach here was mentioned in the doublep's answer (I forgot for toArray method).

With JDK/11, an alternate way of converting a Collection<Foo> to an Foo[] could be to make use of Collection.toArray(IntFunction<T[]> generator) as:

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

As explained by @Stuart on the mailing list(emphasis mine), the performance of this should essentially be the same as that of the existing Collection.toArray(new T[0]) --

The upshot is that implementations that use Arrays.copyOf() are the fastest, probably because it's an intrinsic.

It can avoid zero-filling the freshly allocated array because it knows the entire array contents will be overwritten. This is true regardless of what the public API looks like.

The implementation of the API within the JDK reads:

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

The default implementation calls generator.apply(0) to get a zero-length array and then simply calls toArray(T[]). This goes through the Arrays.copyOf() fast path, so it's essentially the same speed as toArray(new T[0]).


Note:- Just that the API use shall be guided along with a backward incompatibility when used for code with null values e.g. toArray(null) since these calls would now be ambiguous because of existing toArray(T[] a) and would fail to compile.

OscarRyz

For the original see doublep answer:

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

As for the update:

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

If you use Guava in your project you can use Iterables::toArray.

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

For example, you have collection ArrayList with elements Student class:

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
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!