【问题标题】:Create random values of generic type in Java在 Java 中创建泛型类型的随机值
【发布时间】:2016-10-30 01:42:37
【问题描述】:

我有以下:

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

这给了我一个充满随机整数值的列表。我想对此进行概括,以获取随机字符值列表或其他类型的随机值列表。

所以我想要的是一个泛型版本,class RandomList&lt;T&gt;。我可以用“T”替换任何地方的“Integer”,但我被困在Integer r = rand.nextInt();这行,对于不同的类型,它的读法会有所不同。

我正在考虑做以下事情:

  1. 将泛型类型的类传入RandomList
  2. 使用instanceof检查传入的类与所需类型(整数、字符...)并根据检查返回正确的随机值

这有意义吗?是否有另一种/更好的方法来实现我想要的?

【问题讨论】:

    标签: java generics random


    【解决方案1】:

    第一种方法(劣)

    在 Java 中,您无法检查泛型类型,至少在没有反射的情况下无法检查。你用泛型类型赚钱,所以你会做这样的事情:

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

    第二种方法(高级)

    或者,您可以进一步概括这一点并添加Function 以生成随机结果。请注意,这需要 Java 8。如果您不在 Java 8 上,您可以定义一个接口并匿名构造它。

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

    使用以下方法构造一个新实例:

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

    第三种方法(清洁剂)

    编辑:这是我后来想到的,但你似乎使用的是 Java 8,所以你可以只使用流:

    List<Integer> list = Stream.generate(() -> rand.nextInt()).limit(10).collect(Collectors.toList())
    

    【讨论】:

    • 我只推荐 第二种 方法,或者将第一种方法作为另一种选择(这是可疑的并引发很多问题),或者完全删除它。跨度>
    • 优秀。谢谢你。我采用了第二种(功能)方法。
    • @user1583209 我添加了第三种方法,更简洁。
    猜你喜欢
    • 1970-01-01
    • 2016-06-20
    • 2010-09-09
    • 2011-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-18
    相关资源
    最近更新 更多