Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create random values of generic type in Java

I have the following:

public class RandomList {

    private List<Integer> list;

    public List<Integer> getList() {
        return list;
    }

    public RandomList (int n) {
        list = new ArrayList<Integer>();

        Random rand = new Random();
        rand.setSeed(System.currentTimeMillis());

        for (int i=0; i < n; i++)
        {
            Integer r = rand.nextInt();
            list.add(r);
        }
    }   
}

which gives me a list filled with random Integer values. I would like to generalize this, to also get a list of random Character values or perhaps lists of other types' random values.

So what I want is a generic type version, class RandomList<T>. I can replace everywhere "Integer" by "T", but am stuck at the line Integer r = rand.nextInt(); which would read different for different types.

I am thinking of doing the following:

  1. pass in the class of the generic type to RandomList
  2. using instanceof check the passed in class against the desired types (Integer, Character...) and depending on the check return the proper random value

Does this make sense? Is there another/better way to achieve what I want?

like image 696
user1583209 Avatar asked Oct 30 '16 01:10

user1583209


People also ask

How to generate random numbers in Java?

1) java.util.Random. For using this class to generate random numbers, we have to first create an instance of this class and then invoke methods such as nextInt (), nextDouble (), nextLong () etc using that instance. We can generate random numbers of types integers, float, double, long, booleans using this class.

What is random class in Java?

Java Random class. Java Random class is used to generate a stream of pseudorandom numbers. The algorithms implemented by Random class use a protected utility method than can supply up to 32 pseudorandomly generated bits on each invocation.

What is generics in Java?

Generics means parameterized types. The idea is to allow type (Integer, String, … etc, and user-defined types) to be a parameter to methods, classes, and interfaces. Using Generics, it is possible to create classes that work with different data types. An entity such as class, interface, or method that operates on a parameterized type is called ...

How to create a generic array in Java?

As the result of Array#newInstance is of type Object, we need to cast it to E [] to create our generic array. We should also note the convention of naming a type parameter clazz, rather than class, which is a reserved word in Java. 4. Considering ArrayList 4.1. Using ArrayList in Place of an Array


1 Answers

First method (inferior)

In Java you can't check for the generic type, at least not without reflection. You're on the money with the generic type, so you'd do something like this:

public class RandomList<T> {
    private List<T> list;
    private Class<T> clazz;

    public List<T> getList() {
        return list;
    }

    public RandomList (Class<T> clazz, int n) {
        this.clazz = clazz;
        list = new ArrayList<T>();

        Random rand = new Random();
        rand.setSeed(System.currentTimeMillis());

        if (clazz.isAssignableFrom(Integer.class)) {
            for (int i = 0; i < n; i++) {
                Integer r = rand.nextInt();
                list.add(r);
            }
        }
        else {
            throw new IllegalArgumentException("Unsupported class: " + clazz.getName());
        }
    }
}

Second method (superior)

Alternatively, you could generalise this even further and add a Function to produce the randomised results. Note that this requires Java 8. If you're not on Java 8, you could just define an interface and construct that anonymously.

public class RandomList<T> {
    private List<T> list;

    public List<T> getList() {
        return list;
    }

    public RandomList (Function<Random, T> creator, int n) {
        list = new ArrayList<T>();

        Random rand = new Random();
        rand.setSeed(System.currentTimeMillis());

        for (int i = 0; i < n; i++) {
            list.add(creator.apply(rand));
        }
    }
}

Construct a new instance using:

RandomList<Integer> list = new RandomList<>(rand -> rand.nextInt(), 10);

Third method (cleaner)

Edit: This occurred to me later, but you seem to be using Java 8, so you could just use streams:

List<Integer> list = Stream.generate(() -> rand.nextInt()).limit(10).collect(Collectors.toList())
like image 52
KennethJ Avatar answered Oct 22 '22 20:10

KennethJ