28

Is there a way to fill an array using java 8 Supplier ?

I would like to write:

Supplier<Object> supplier = () -> new Object(); Object[] array = new Object[size]; Arrays.fill(array, supplier); 

Note: I know i could write my own method.

4 Answers 4

36

In case you want to create new array filled with results generated by Supplier you can use

Object[] array = Stream.generate(supplier) .limit(arraySize) .toArray(); // will generate new *Object[]* array 

For different types than Object[] you can use toArray(IntFunction<YourType[]> generator); like toArray(YourType[]::new) (credits to @Holger).

String[] array = Stream.generate(supplier) .limit(10) .toArray(String[]::new); //now *String[]* array will be returned 

Streams also allow us to work with most "popular" primitive types which are int long and double. For instance we can use IntStream#toArray to create int[] holding elements from IntStream. To "fill" IntStream with elements from supplier we can use IntStream.generate(intSupplier) like

int[] array = IntStream.generate(()->1) .limit(5) .toArray(); //returns `new Int[]{1,1,1,1,1} 

In case when you want to fill already existing array with data from Supplier see answer posted by Stuart Marks based on Arrays.setAll(array, supplier) which aside from handling arrays of objects also supports some arrays of primitive types: double[] int[] and long[] .

Other alternative is to use creative solution from @Hogler's comment:

Arrays.asList(array).replaceAll(x -> supplier.get()); //you can even overwrite a range using `subList` 

just be aware that Arrays.asList is designed to work with arrays of reference type (non-primitive ones), so it will not handle "properly" arrays like int[] as explained by Jon Skeet in answer: https://stackoverflow.com/a/1467940.

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks, this is very close to what i am looking for. I gave my example with Object but what if i want to use another type like Integer or Date ?
@gontard: For generating an array of MyType, use toArray(MyType[]::new)
Ok. Could you add this alternative to your answer ? A last question: is it possible to do the same thing with a generic type ? I know it is not possible to create an array of generics but may be...
As a remark, you can fill an already existing array in the following “creative” way: Arrays.asList(array).replaceAll(x->supplier.get());. You can even overwrite a range using subList.
Using the creative way one should be careful with primitive types. First example is ok: System.out.println(Arrays.asList( new Integer[]{1,2,3,4,5})); [1, 2, 3, 4, 5] Second example is a list containing one single element which is the whole array: System.out.println(Arrays.asList( new int[]{1,2,3,4,5})); [[I@53b32d7]
33

In java.util.Arrays there is

<T> void Arrays.setAll(T[] array, IntFunction<T> generator) 

This doesn't take a supplier; instead it takes an IntFunction whose input argument is the array index being filled. If your objects aren't dependent upon the destination array index, you can disregard the parameter and call a supplier like this:

Arrays.setAll(array, i -> supplier.get()); 

There are overloads for arrays of primitives as well as arrays of reference type. There is also a corresponding family of methods parallelSetAll() that does the same thing, except in parallel. (It uses streams internally.)

2 Comments

It would be really lovely if there were an overload of this method, that took a Supplier<T> as its last argument, instead of the IntFunction.
A variant on this Arrays.setAll(array, i -> new T());
0

You could easily write your own:

public static <T> void fillArray(T[] array, Supplier<? extends T> supplier) { for(int k = 0; k < array.length; k++) array[k] = supplier.get(); } 

1 Comment

Thanks, but i should have been more specific in my question. I know i could write method with java.
-1

Alternative to Pshemo's solution you could use map method.

Object[] array = new Object[size]; array = Arrays.stream(array).map(a -> new Object()).toArray(); 

2 Comments

@Pshemo: I got. I thought he wanted a usual filling with same object.
In this solution array created twice.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.