Randomly getting value with percentage of chance in Java



I would like to be able to return (and in our case, for the example, display) an item of an enumeration, according to a certain predefined percentage of chance for each item. An illustration in code of this enumeration just below :

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;
    }

}

Also, these items will be stored in a List.

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());
    }

}

Namely that, as in this example, two items can have the same percentage of chance to appear.

I also looked at the following topic (Java Random Percentage Chance) but in my case, the percentages are not predefined in the expressions directly but in the enumeration.

So I would appreciate your help. Thank you in advance for taking the time to help me.

Answer

BE SIMPLE!!!

  1. Create an array.
  2. Put into this array all items, percentage count each.
  3. Shuffle the array.
  4. Retrieve random element form this array.

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;
        }

    }
}


Source: stackoverflow