K.Torp
K.Torp

Reputation: 45

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!

Upvotes: 1

Views: 192

Answers (1)

Nicolas Filotto
Nicolas Filotto

Reputation: 44965

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 <C extends Collection<Integer>> C fillWithInt(Class<C> 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:

Set<Integer> set = fillWithInt(HashSet.class, 1, 10);

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

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

Example:

Set<Integer> set = fillWithInt(HashSet::new, 1, 10);

Upvotes: 2

Related Questions