java - 从 HashMap 中随机获取值

标签 java

所以我有一个类型为 <T,Integer> 的 hashmap . T 是通用类型。

T 是任何对象,整数是我们当前在 map 中拥有的该对象的数量。

例如,一个字符串“shirt”,它的值映射为 3。

我想构建一个名为 random 的方法,它会根据对象的当前分布从 map 中返回一个随机对象。

意思是,如果我的 map 中有 2 个键……“衬衫”和“裤子”。我的 map 中有 3 件“衬衫”和 7 件“裤子”。分布应该是 30% 的时间是一件衬衫被退回,70% 的时间是“裤子”将被退回。

我将如何使用随机生成器做这样的事情?

最佳答案

该 map 数据类型使得实现您的要求变得相当困难。更好的数据结构将使它变得容易得多。有多种可能的数据结构可以优化不同的事物。

少数不同值/值计数的解决方案

如果您需要经常选择随机值,并且您没有太多不同的值/值计数,那么这里有一个非常有效的解决方案:

一个简单的List<T>怎么样?相反?

// Calculate this in advance
List<T> values = 
map.entrySet()
   .stream()
   .flatMap(entry -> Stream.generate(() -> entry.getKey())
                           .limit(entry.getValue()))
   .collect(Collectors.toList());

根据您的示例,此数组现在将包含 "Shirts" 的 3 个副本和 7 份 "Pants"

现在很容易根据您想要的概率分布随机选择一个值:

SecureRandom random = new SecureRandom();
T randomValue = values.get(random.nextInt(values.length));

证明:

Map<String, Integer> result = new HashMap<>();
for (int i = 0; i < 100000; i++)
    result.compute(values.get(random.nextInt(values.length)), 
                  (s, j) -> j == null ? 1 : j + 1);

System.out.println(result);

... 产量:

{Shirts=29955, Pants=70045}

关于java - 从 HashMap 中随机获取值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40205178/

相关文章:

java - JSP 中的 JSON 和 Jquery 树

java - 解决方案。 numfound 是什么意思?

java - 方法内可变数组长度

java - 通过 DB2 Express-C 执行 PreparedStatement 时出错

java - 如何检查 MongoDB 中是否存在字段?

java - 如何在 JPA 的两列上运行像 SUM 这样的聚合函数并显示它们的结果?

java - 在已部署的系统中使用 session.setAttribute

java - Android Toast 不显示

java - 如何将测试库(例如 JUnit)添加到 Intellij "Create Test Class"对话框

Java正则表达式匹配所有字符,除了