小編典典
最簡單的方法是創建一個可能數字的列表(1..20或任何數字),然后用對其進行混洗Collections.shuffle。然后,只需考慮你想要的許多元素。如果你的范圍最終等于你需要的元素數量(例如,用于洗牌的卡片),則這非常好。
如果你想要(說)1..10,000范圍內的10個隨機元素,那么效果就不太好-你最終會不必要地進行大量工作。到那時,最好保留到目前為止已生成的一組值,并保持循環生成數字直到下一個不存在為止:
if (max < numbersNeeded)
{
throw new IllegalArgumentException("Can't ask for more numbers than are available");
}
Random rng = new Random(); // Ideally just create one instance globally
// Note: use LinkedHashSet to maintain insertion order
Set generated = new LinkedHashSet();
while (generated.size() < numbersNeeded)
{
Integer next = rng.nextInt(max) + 1;
// As we're adding to a set, this will automatically do a containment check
generated.add(next);
}
但是,請謹慎選擇設置-我非常有意地使用LinkedHashSet它,因為它會保持插入順序,我們在這里關心它。
另一種選擇是通過每次減小范圍并補償現有值來始終取得進展。因此,舉例來說,假設你要使用0..9范圍內的3個值。在第一次迭代中,你將生成0..9范圍內的任何數字-假設你生成了4。
在第二次迭代中,你將生成一個范圍為0..8的數字。如果生成的數字小于4,則應保持原樣…否則將其添加一個。這樣得到的結果范圍是0..9,而不是4。假設我們以這種方式得到7。
在第三次迭代中,你將生成一個范圍為0..7的數字。如果生成的數字小于4,則將其保持原樣。如果是4或5,則要加1。如果是6或7,則要加兩個。這樣,結果范圍是0..9,沒有4或6。
2020-02-25