K.Torp K.Torp - 9 days ago 6
Java Question

Fill arbitrary collection with Integers in Java

First question asked, please be understanding to formatting mistakes.

In java, using streams, it's possible to populate some collections with Integers by using

Intstream
,

IntStream.range(from,to).boxed().collect(Collectors.toCollection(HashSet::new));


Where if you replace
HashSet
with for example
ArrayList
or
LinkedList
you'll simply return that specified collection instead.

Using this, how could you set up a method where you can specify the desired collection interface to populate? What I'm looking for is something like this:

public returnType fillWithInt(Class<?> t, int from, int to){
return IntStream.range(from,to)
.boxed()
.collect(Collectors.toCollection(t::new));
}


Trying this I get a warning:


Class(java.lang.ClassLoader)' has private access in 'java.lang.Class.


I've been on this the whole day and can't figure out what to do.

I might as well say as a disclaimer, I'm very new at programming so I might be tackling this completely wrong. If that's the case I hope to be given a nudge in the right direction!

Answer

A method reference cannot be defined using an instance of class as you try to achieve, so you need to implement the Supplier of your target Collection.

You can do it using reflection as next:

public Collection<Integer> fillWithInt(Class<? extends Collection> t, int from, int to) {
    return IntStream.range(from,to)
        .boxed()
        .collect(
            Collectors.toCollection(
                () -> {
                    try {
                        return t.newInstance();
                    } catch (InstantiationException | IllegalAccessException e) {
                        throw new IllegalArgumentException(e);
                    }
                }
            )
        );
}

Example:

Collection<Integer> collection = fillWithInt(HashSet.class, 1, 10);

Or simply by providing the Supplier as parameter of your method, as next:

public Collection<Integer> fillWithInt(Supplier<Collection<Integer>> supplier, 
    int from, int to){
    return IntStream.range(from,to)
        .boxed()
        .collect(Collectors.toCollection(supplier));
}

Example:

Collection<Integer> collection = fillWithInt(HashSet::new, 1, 10);
Comments