从相似名称或EnumSet中获取随机枚举的Java代码。
问题的出现原因是在Java 8中使用了一个方法来从给定的Set集合中随机获取一个枚举元素。然而,这个方法可能会导致NoSuchElementException异常的抛出,因为在调用get()方法之前没有进行检查。这个异常可以被忽略,前提是保证底层元素集合在并发操作中没有被改变(流操作不是自动原子的)。
解决方法是使用orElse()方法替代get()方法。这样,如果流操作没有找到任何元素,则会返回null而不是抛出异常。同时,为了确保Random().nextInt()方法的参数不超过Set集合的大小,需要在计算随机数的范围时使用set.size() - 1而不是set.size()。
下面是整理的文章:
在Java 8中,我们需要从一个给定的Set集合中随机获取一个枚举元素。为了实现这个功能,我们可以使用以下方法:
static <E> E getRandomSetElement(Set<E> set) { return set.stream().skip(new Random().nextInt(set.size())).findFirst().orElse(null); }
然而,这个方法可能会导致NoSuchElementException异常的抛出。为什么不直接使用findFirst().get()而是使用orElse()呢?
如果我们在没有进行检查的情况下调用get()方法,它可能会抛出NoSuchElementException异常。这个异常可以被忽略,但前提是我们要确保底层元素集合在并发操作中没有被改变。因为流操作不是自动原子的,所以需要注意这一点。
为了解决这个问题,我们可以使用orElse()方法替代get()方法。如果流操作没有找到任何元素,则会返回null而不是抛出异常。
此外,在计算随机数的范围时,我们需要注意一个重要的细节。Random().nextInt()方法返回的随机数不包括其参数,即不包括set.size()。因此,为了确保随机数不超过Set集合的大小,我们应该使用set.size() - 1而不是set.size()作为计算范围的参数。
通过以上的解决方法,我们可以在Java 8中从一个给定的Set集合中随机获取一个枚举元素。这样,我们就可以轻松地处理类似的问题了。
问题的原因是,Java中的Collections类提供了用于打乱整个集合的方法,但这些方法只适用于实现了List接口的集合,不适用于实现了Set接口的集合。
解决方法是,如果需要从集合中随机选择一个元素,可以将Set集合转换为List集合,然后使用List.get(new Random().nextInt(size))方法来获取随机元素。代码示例如下:
Listlist = new ArrayList<>(set); E randomElement = list.get(new Random().nextInt(list.size()));
这样就可以从相似名称的枚举或EnumSet集合中随机选择一个枚举元素了。
问题的出现原因是如果要从一个HashSet中随机获取一个元素,使用循环遍历的方法会比较慢,因为平均需要(n / 2)次迭代才能找到随机的对象。并且在Java中,HashSet的规范不允许直接访问底层的桶,所以无法更高效地选择随机元素。
解决方法是将HashSet复制到一个数组中,然后通过索引直接访问元素,这样的时间复杂度为O(1)。可以使用myHashSet.toArray()
方法来实现。但是需要注意,如果HashSet发生变化,即有元素被添加或删除,就需要重新复制数组。此外,还需要考虑空桶的情况。
此外,对于整数类型的元素,可以使用上述方法获取随机元素。而对于其他类型的元素,可以参考下面的答案:stackoverflow.com/a/51412979/4428219。