Как вы можете получить рандомизированное подмножество списка в Java, не используя Collections.shuffle? - PullRequest
1 голос
/ 06 августа 2011

У меня есть List объектов, этот список может содержать тысячи элементов.

Я хочу получить подмножество 10, 20, 34, 56 (любую часть размера, которую выберет пользователь), это подмножество должно быть выбрано случайным образом, и у меня не может быть дубликатов.

Будет ли Collections.shuffle() достаточным для больших списков POJO? Или есть более эффективный / безопасный способ сделать это?

Если взять мой пример здесь, если бы myStrings содержал 50 000 строк, было бы неплохо назвать Collections.shuffle(), если бы вы хотели только 5 элементов?

public class ShuffleMe
{

    public static void main(String[] args)
    {
        int NUM_OF_ELEMENTS_TO_PICK = 3;
        List<String> myStrings = new ArrayList<String>();

        myStrings.add("A");
        myStrings.add("B");
        myStrings.add("C");
        myStrings.add("D");
        myStrings.add("E");
        myStrings.add("F");

        Collections.shuffle(myStrings);

        for (int i = 0; i < NUM_OF_ELEMENTS_TO_PICK; i++)
        {
            System.out.println(myStrings.get(i));
        }
    }
}

Ответы [ 3 ]

4 голосов
/ 06 августа 2011

Если количество нужных вам предметов намного меньше размера коллекции, просто нарисуйте их случайным образом:

Set<Integer> randSubSet = new HashSet<Integer>();
while(randSubSet.size() < NUM_OF_ELEMENTS_TO_PICK) {
    randSubSet.add((int)(Math.random()*myStrings.size()));
}
for (int i : randSubSet) {
    System.out.println(myStrings.get(i));
}
4 голосов
/ 06 августа 2011

Перестановка всего списка будет пустой тратой ресурсов, если то, что вы хотите, будет значительно меньше.Лично я бы просто выбрал n уникальных случайных чисел от 0 до размера и использовал бы объекты с этими индексами для рандомизированного подмножества.

Если вы говорите о выборе случайного подмножества, очень близкого к размерувся коллекция, то, скорее всего, вам лучше всего позвонить Collections.shuffle() и выбрать первые n записи.Но если мы говорим о ~ 5/50000, определенно используйте вышеуказанный подход.

1 голос
/ 06 августа 2011

Используйте перетасовку Фишера-Йейтса, но только запустите ее достаточно далеко, чтобы выбрать необходимое количество элементов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...