Java 8 fill array with supplier

安稳与你 提交于 2019-12-19 12:24:05

问题


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.


回答1:


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 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 of its problems with array of primitive types explained by Jon Skeet at https://stackoverflow.com/a/1467940.




回答2:


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




回答3:


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



回答4:


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

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


来源:https://stackoverflow.com/questions/25077203/java-8-fill-array-with-supplier

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