2016-11-29 2 views
-1

Я пытаюсь выяснить, как добавить 6 случайно сгенерированных чисел в HashSet. Я получаю результаты, но они непоследовательны. Иногда он выводит 6 номеров на консоль, а в других случаях он печатает 5 номеров на консоли.Генератор случайных чисел, дающий непоследовательные результаты

Я новичок в этом деле только этим утром, поэтому извиняюсь, если это явно очевидно, и спасибо за вашу помощь.

HashSet<Integer> generatedLotteryNumbers = new HashSet<Integer>(); 
Random r = new Random(); 

for(int i=0; i<6; i++){ 
    generatedLotteryNumbers.add(r.nextInt(49)); 
} 

System.out.println(generatedLotteryNumbers); 
+0

Просто выполните некоторые исследования особенностей Java-наборов, и вы узнаете, что здесь происходит. – Tom

+1

Любите титул. – shmosel

+0

Да, я был не совсем уверен, как это сказать, shmosel – Schming

ответ

3

A Set не может содержать повторяющиеся значения, поэтому, если генератор производит одинаковое число два раза, он будет удален. Вместо этого, вы должны петля на основе размера Set (или использовать List):

while (generatedLotteryNumbers.size() < 6) { 
    generatedLotteryNumbers.add(r.nextInt(49)); 
} 

Если вы используете Java 8, другой вариант заключается в использовании Random#ints для генерации Stream, который можно использовать непосредственно создайте свой Set.

Set<Integer> generatedLotteryNumbers = r.ints(0, 49) 
             .distinct() 
             .limit(6) 
             .boxed() 
             .collect(Collectors.toSet()); 
+0

Интересно. Я не знал, что вы можете называть 'distinct()' бесконечным потоком. – shmosel

+0

Небольшая проблема с этим ответом состоит в том, что он теоретически * может бесконечно работать, а производительность может ухудшиться, так как целевой размер (6) приближается к максимальному значению (49). Я думаю, что более правильным подходом было бы перетасовать массив всех потенциальных значений и выбрать первые n элементов. – shmosel

+0

@schmosel Хорошо, если мы являемся теоретическими, вероятность бесконечно сходится к 0 с каждой итерацией. Таким образом, теоретически существует 0% вероятность бесконечности цикла. Не могли бы вы объяснить, что вы имеете в виду с проблемами производительности? – 4castle

3

Это потому, что GeneratedLotteryNumbers является HashSet (который действует как набор) и HashSet в Java не вставляет элемент, который уже присутствует в нем и, следовательно, не допускает дубликатов, так что если вы получая менее 6 элементов, это потому, что некоторые элементы являются общими и, следовательно, сохраняются только один раз.

Лучше попробовать это:

ArrayList<Integer> GeneratedLotteryNumbers = new ArrayList<Integer>(); 
Random r = new Random(); 
for(int i=0; i<6; i++){ 
    GeneratedLotteryNumbers.add(r.nextInt(49)); 
} 

Для обнаружения вставки дубликата, захват boolean возвращенное методом Set::add, успешно добавлен TRUE и FALSE, если дубликат.

+0

Ах, правильно. Я знал, что он только однажды сохранил значение, но я не понял, что он просто опустил дубликат. Спасибо. – Schming

+1

Hashset не позволяет вставлять дубликаты, для получения дополнительной информации см. Это: http://stackoverflow.com/questions/12940663/does-adding-a-duplicate-value-to-a-hashset-hashmap-replace- предыдущее значение, и, пожалуйста, отметьте ответ как принятый, если он решит вашу проблему. :) @Schming – Jarvis

+1

@Schming Он опустит дубликат, но метод 'add' вернет' false', когда это произойдет. Так что это не совсем тихо. – 4castle

Смежные вопросы