【问题标题】:How to return a random value within a range, from a Map with Integer and List of Longs in Java如何从Java中的整数和长列表中返回一个范围内的随机值
【发布时间】:2019-10-31 12:29:41
【问题描述】:

我试图找到一种方法,使用ThreadLocalRandom 从提供的不同范围列表中获取随机值,并从方法中返回该随机值。我一直在尝试不同的方法,但运气不佳。

我试过了:

private static final Long[][] values = {
    { 233L, 333L },
    { 377L, 477L },
    { 610L, 710L }
};
// This isn't correct
long randomValue = ThreadLocalRandom.current().nextLong(values[0][0]);

但我不知道如何从中获取特定范围的随机值,所以我想尝试Map 方法,我尝试创建一个整数映射和长列表:

private static Map<Integer, List<Long>> mapValues = new HashMap<>();

{{233L, 333L}, {377L, 477L}, {610L, 710L}} // ranges I want

我不确定如何将这些值范围存储到地图中。

我尝试过添加值,例如:

// Need to get the other value for the range in here, in this case 333L
map.put(1, 233L);

我不知道如何将 333L 添加到列表中,我搜索并尝试了各种方法,但总是出现错误,例如:found 'long', required List

我希望 Map 中的 Integer 是关联范围的 id,例如 1 表示 233L-333L,这样我就可以先告诉它,从 Map 中获取一个随机的 Int 键,例如 1,然后然后使用ThreadLocalRandom.current().nextLong(origin, bound),其中 origin 为 233L,bound 为 333L,然后返回 233L-333L 范围内的随机值。

我不确定这是否可能,或者我只是以错误的方式处理这个问题 - 感谢任何指导/帮助!

【问题讨论】:

  • 列表中是否总是只有两个元素表示范围?如果是这样,origin = longs[0]bound = longs[1] 不会吗?
  • 是的,有可能。你为什么不试一试?但是请注意,如果您的范围没有相同的大小,这不会为您提供所有数字的均匀分布。另请注意,如果基本上是地图,则数组的索引是键: values[0] 等效于 mapValues.get(0)
  • 谢谢!我已经尝试过,我认为我的主要问题是我根本无法弄清楚如何将值添加到地图中 - 为清楚起见编辑了问题

标签: java arrays list dictionary arraylist


【解决方案1】:
int range = ThreadLocalRandom.current().nextInt(3);
long randomValue = ThreadLocalRandom.current().nextLong(values[range][0],values[range][1]);

这将适用于您首先尝试的阵列解决方案。首先你选择范围然后你得到随机值。

【讨论】:

  • 当,谢谢!然后我可以从方法中返回 randomValue 吗?
【解决方案2】:

这很简单。你的long[][] 会很好。

首先,选择一个随机索引,然后在values[index][0]values[index][1]之间选择一个long1

long[][] values = {
    { 233L, 333L },
    { 377L, 477L },
    { 610L, 710L }
};

// Select a random index
int index = ThreadLocalRandom.current().nextInt(0, values.length);

// Determine lower and upper bounds
long min = values[index][0];
long max = values[index][1];
long rnd = ThreadLocalRandom.current().nextLong(min, max);

当然,你也可以abstract it away进入一些方便的类。

请注意,为了使值的分布均匀,所有范围必须具有相同的大小(您的代码中似乎就是这种情况)。

实现均匀分布

但是,如果您想支持不同的范围而必须保持均匀分布,则需要另一种方法。

我们可以计算单个随机数,上限为可能值的总数。然后我们可以检查要在哪个“桶”中检索值。

Here is a working example。为了测试所谓的均匀分布,随机数生成一百万次。如您所见,每个值大约出现 200,000 次。


1 在我的示例中,上限是独占。这与 Java 标准库中的许多方法一致,例如 ThreadLocalRandom.nextLong(origin, bound)LongStream.range(long start, long end)

【讨论】:

  • 啊,有道理!谢谢!我可以在一个方法中拥有所有这些,在这个例子中,该方法将返回 rnd?
  • 没错。您还可以将此代码放入一些方便的类中。 (请参阅帖子中的链接。)
  • 但请记住:除非所有范围的大小都相等,否则这不会提供所有值的均匀分布,正如 JB Nizet 已经提到的那样。
  • 哇,这太棒了 - 我真的很感激!非常清楚。非常感谢!
【解决方案3】:

最简单的就是最直接的。

   private static final long[][] values = { { 233L, 333L
         }, { 377L, 477L
         }, { 610L, 710L
         }
   };

   public static void main(String[] args) {
      for (long v[] : values) {
         long low = v[0];
         long high = v[1];
         System.out.println("Between " + low + " and " + high + " -> "
               + getRandom(low, high));
      }
   }

   public static long getRandom(long low, long high) {
      // add 1 to high to make range inclusive
      return ThreadLocalRandom.current().nextLong(low, high + 1);
   }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-04
    相关资源
    最近更新 更多