以 Java 中的概率随机获取值
Randomly getting value with percentage of chance in Java
我希望能够 return(在我们的示例中,显示)枚举的一个项目,根据每个项目的某个预定义概率百分比。下面是此枚举的代码示例:
package me.lucas.test;
public enum Item {
ITEM_1("Item 1", 30),
ITEM_2("Item 2", 30),
ITEM_3("Item 3", 10),
ITEM_4("Item 4", 65);
private final String name;
private final int percentage;
Item(String name, int percentage) {
this.name = name;
this.percentage = percentage;
}
public String getName() {
return name;
}
public int getPercentage() {
return percentage;
}
}
此外,这些项目将存储在列表中。
package me.lucas.test;
import java.util.ArrayList;
import java.util.List;
public class Program {
private final List<Item> items = new ArrayList<>();
/**
* Displays an item among those in the list, according to their percentage chance of appearing.
* @param items The items
*/
public void displayItem(List<Item> items) {
Item item;
item = ?
System.out.println("Selected item : " + item.getName() + " with percentage : " + item.getPercentage());
}
}
也就是说,如本例所示,两个项目可以有相同的出现几率。
我还查看了以下主题 (),但在我的例子中,百分比不是直接在表达式中预定义的,而是在枚举中预定义的。
非常感谢您的帮助。预先感谢您抽出时间帮助我。
从视觉上讲,您实施了机会之轮
轮子会停在1到100的任意一个位置,现在你只需要读出这个位置有哪些可能性。如果总和小于 100,则此位置可能没有任何内容。如果总和 > 100,则此位置可能不止一项。
所有百分比都从 1 到 100 换行 - 通过取模实现。您生成的随机数介于 1 和 100 之间,或者在这种情况下介于 0 和 99 之间(请参阅 Random 的 Javadoc)。
在代码中,这可能如下所示:
public class RandomExample<T extends Object> {
List<Item> items = new LinkedList<>();
Random rand = new Random();
public void addItem(int percentage, T object) {
items.add(new Item(percentage, object));
}
public List<Item> getRandom() {
List<Item> result = new ArrayList<>();
int hit = rand.nextInt(100);
items.forEach(i -> {
if(i.isHit(hit)) {
result.add(i);
}
});
return result;
}
public class Item {
private int percentage;
private T object;
private int hitLow;
private int hitHigh;
public Item(int percentage, T object) {
this.percentage = percentage;
this.object = object;
int sum = 0;
for(Item i : items) {
sum+=i.getPercentage();
}
hitLow = sum % 100;
hitHigh = (sum+percentage) % 100;
}
public int getPercentage() {
return percentage;
}
public T getObject() {
return object;
}
public boolean isHit(int hitVal) {
boolean isHit = hitLow == hitHigh; //exactly 100%
isHit |= hitLow <= hitVal && hitHigh >= hitVal;
return isHit;
}
}
}
方法 RandomExample.Item.isHit(int)
仍然需要一个额外的条件来正确处理机会,它环绕 100(例如 hitLow = 90
和 hitHigh = 10
)。但是您了解了这个概念,应该能够根据您的需要对其进行调整。
您需要问自己的另一个问题是:如果有人通过的百分比大于 100 会发生什么。我的直觉告诉您应该抛出异常。但那是你决定和实施的。
要简单!!!
- 创建数组。
- 将所有项目放入此数组,
percentage
计算每个项目。
- 随机排列数组。
- 从该数组中检索随机元素。
public class Foo {
public static void main(String... args) {
Item[] items = generateItemArray();
Random random = new Random();
while (true) {
System.out.println(items[random.nextInt(items.length)]);
}
}
private static Item[] generateItemArray() {
List<Item> items = new ArrayList<>();
for (Item item : Item.values())
for (int i = 0; i < item.percentage; i++)
items.add(item);
Collections.shuffle(items);
return items.toArray(Item[]::new);
}
public enum Item {
ITEM_1("Item 1", 30),
ITEM_2("Item 2", 30),
ITEM_3("Item 3", 10),
ITEM_4("Item 4", 65);
private final String name;
private final int percentage;
Item(String name, int percentage) {
this.name = name;
this.percentage = percentage;
}
}
}
我希望能够 return(在我们的示例中,显示)枚举的一个项目,根据每个项目的某个预定义概率百分比。下面是此枚举的代码示例:
package me.lucas.test;
public enum Item {
ITEM_1("Item 1", 30),
ITEM_2("Item 2", 30),
ITEM_3("Item 3", 10),
ITEM_4("Item 4", 65);
private final String name;
private final int percentage;
Item(String name, int percentage) {
this.name = name;
this.percentage = percentage;
}
public String getName() {
return name;
}
public int getPercentage() {
return percentage;
}
}
此外,这些项目将存储在列表中。
package me.lucas.test;
import java.util.ArrayList;
import java.util.List;
public class Program {
private final List<Item> items = new ArrayList<>();
/**
* Displays an item among those in the list, according to their percentage chance of appearing.
* @param items The items
*/
public void displayItem(List<Item> items) {
Item item;
item = ?
System.out.println("Selected item : " + item.getName() + " with percentage : " + item.getPercentage());
}
}
也就是说,如本例所示,两个项目可以有相同的出现几率。
我还查看了以下主题 (
非常感谢您的帮助。预先感谢您抽出时间帮助我。
从视觉上讲,您实施了机会之轮
轮子会停在1到100的任意一个位置,现在你只需要读出这个位置有哪些可能性。如果总和小于 100,则此位置可能没有任何内容。如果总和 > 100,则此位置可能不止一项。
所有百分比都从 1 到 100 换行 - 通过取模实现。您生成的随机数介于 1 和 100 之间,或者在这种情况下介于 0 和 99 之间(请参阅 Random 的 Javadoc)。
在代码中,这可能如下所示:
public class RandomExample<T extends Object> {
List<Item> items = new LinkedList<>();
Random rand = new Random();
public void addItem(int percentage, T object) {
items.add(new Item(percentage, object));
}
public List<Item> getRandom() {
List<Item> result = new ArrayList<>();
int hit = rand.nextInt(100);
items.forEach(i -> {
if(i.isHit(hit)) {
result.add(i);
}
});
return result;
}
public class Item {
private int percentage;
private T object;
private int hitLow;
private int hitHigh;
public Item(int percentage, T object) {
this.percentage = percentage;
this.object = object;
int sum = 0;
for(Item i : items) {
sum+=i.getPercentage();
}
hitLow = sum % 100;
hitHigh = (sum+percentage) % 100;
}
public int getPercentage() {
return percentage;
}
public T getObject() {
return object;
}
public boolean isHit(int hitVal) {
boolean isHit = hitLow == hitHigh; //exactly 100%
isHit |= hitLow <= hitVal && hitHigh >= hitVal;
return isHit;
}
}
}
方法 RandomExample.Item.isHit(int)
仍然需要一个额外的条件来正确处理机会,它环绕 100(例如 hitLow = 90
和 hitHigh = 10
)。但是您了解了这个概念,应该能够根据您的需要对其进行调整。
您需要问自己的另一个问题是:如果有人通过的百分比大于 100 会发生什么。我的直觉告诉您应该抛出异常。但那是你决定和实施的。
要简单!!!
- 创建数组。
- 将所有项目放入此数组,
percentage
计算每个项目。 - 随机排列数组。
- 从该数组中检索随机元素。
public class Foo {
public static void main(String... args) {
Item[] items = generateItemArray();
Random random = new Random();
while (true) {
System.out.println(items[random.nextInt(items.length)]);
}
}
private static Item[] generateItemArray() {
List<Item> items = new ArrayList<>();
for (Item item : Item.values())
for (int i = 0; i < item.percentage; i++)
items.add(item);
Collections.shuffle(items);
return items.toArray(Item[]::new);
}
public enum Item {
ITEM_1("Item 1", 30),
ITEM_2("Item 2", 30),
ITEM_3("Item 3", 10),
ITEM_4("Item 4", 65);
private final String name;
private final int percentage;
Item(String name, int percentage) {
this.name = name;
this.percentage = percentage;
}
}
}