The easiest way to transform collection to array?

JavaArraysCollectionsTransformation

Java Problem Overview


Suppose we have a Collection<Foo>. What is the best (shortest in LoC in current context) way to transform it to Foo[]? Any well-known libraries are allowed.

UPD: (one more case in this section; leave comments if you think it's worth to create another thread for it): What about transforming Collection<Foo> to Bar[] where Bar has constructor with 1 parameter of type Foo i.e. public Bar(Foo foo){ ... } ?

Java Solutions


Solution 1 - Java

Where x is the collection:

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

Solution 2 - Java

Alternative solution to the updated question using Java 8:

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

Solution 3 - Java

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

Solution 4 - Java

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.

Solution 5 - Java

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

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

Solution 6 - Java

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).

Solution 7 - Java

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

Solution 8 - Java

Actually in modern Java, the version without setting the explicit size is faster. See this SO answer:

https://stackoverflow.com/questions/174093/toarraynew-myclass0-or-toarraynew-myclassmylist-size

This is backed up by independent research and the team at IntelliJ.

That is, this is the fastest approach today:

Foo[] foos = x.toArray(new Foo[0])

Or, even better, with a bit of safety:

Foo[] foos = x == null ? null : x.toArray(new Foo[0])

Solution 9 - Java

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

Solution 10 - Java

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRomanView Question on Stackoverflow
Solution 1 - Javauser319799View Answer on Stackoverflow
Solution 2 - JavaJulesView Answer on Stackoverflow
Solution 3 - JavaAndreas DolkView Answer on Stackoverflow
Solution 4 - JavaNamanView Answer on Stackoverflow
Solution 5 - JavaAndrea BergonzoView Answer on Stackoverflow
Solution 6 - JavaRomanView Answer on Stackoverflow
Solution 7 - JavaOscarRyzView Answer on Stackoverflow
Solution 8 - JavaAdam WiseView Answer on Stackoverflow
Solution 9 - JavaRustam ShafigullinView Answer on Stackoverflow
Solution 10 - JavaJagadeesh HNView Answer on Stackoverflow