我想随机数但上面的编码没有重复是正确的吗?

i would like to random number but no repetition im coding above is it correct?

我想做的是生成随机数但没有重复我在上面编码是否正确?

public static void main(String[] args) {
    ArrayList<Integer> arrayLast = new ArrayList<Integer>();
    for (int arrayitems : getArray(10, 100)) {
        arrayLast.add(arrayitems);
    }
}

public static ArrayList<Integer> getArray(int arraysize, int range){
    ArrayList<Integer> array = new ArrayList<Integer>();
    ArrayList<Integer> arraybase = new ArrayList<Integer>();
    Random rnd = new Random();
    for (int i = 1; i <= range; i++) {
        arraybase.add(new Integer(i));
    }

    int k =0;       
    for (int j = 0; j < arraysize; j++) {
        if(range>arraysize) {
            int sayi = rnd.nextInt(range-arraysize);
            array.add(arraybase.get(sayi));
            arraybase.remove(sayi);
        }
        else {  
            int sayi = rnd.nextInt(arraysize-k);
            array.add(arraybase.get(sayi));
            arraybase.remove(sayi);
            k++;
        }
    }
    Collections.shuffle(array);         
    return array;
}  

您的逻辑不必要地复杂。更简单的方法如下:

import java.util.HashSet;
import java.util.Random;
import java.util.Set;

public class Main {
    public static void main(String[] args) {
        Set<Integer> set = new HashSet<Integer>();
        final int SIZE = 10;
        final int RANGE = 100;
        Random random = new Random();
        while (set.size() != SIZE) {
            set.add(random.nextInt(RANGE));
        }
        System.out.println(set);
    }
}

样本运行:

[83, 67, 86, 39, 56, 26, 92, 60, 13, 94]

请注意,Set 仅保留唯一值。因此,添加到其中的任何重复随机数将被自动丢弃。


或者,

import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        final int SIZE = 10;
        final int RANGE = 100;
        Random random = new Random();
        List<Integer> list = IntStream.generate(() -> random.nextInt(RANGE)).distinct().limit(SIZE).boxed()
                .collect(Collectors.toList());
        System.out.println(list);
    }
}

样本运行:

[54, 62, 14, 5, 30, 76, 7, 9, 63, 61]

使用 Java 8+ 中的 Stream API,您可以生成 n 个不同的整数,范围从 origin(含)到 bound(独家)通过使用此方法:

public static List<Integer> randomInts(int n, int origin, int bound) {
    return ThreadLocalRandom.current().ints(origin, bound)
            .distinct()
            .limit(n)
            .collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
}

示例:

// generate 15 distinct random numbers greater than or equal to 10 and less than 90
List<Integer> randoms = randomInts(15, 10, 90);

我推荐这样做。如果大小和范围明显不同,则可以使用 setsstreamsdistinct。但如果大小和范围接近,这些方法可能需要相对较长的时间才能完成。

这个算法的缺点是它首先初始化了一个内部数组。我发现这在大多数情况下是微不足道的,并且对于大小和范围都很大的值,速度的提高非常显着。

它的工作原理如下:

  • 假设一个从 0N 的整数数组。
  • 0N之间生成一个随机整数k
  • 将该值分配给 return 数组。
  • 用第 N 个值替换第 k 个值
  • 然后将 N 减少 1
  • 并重复直到 N == 0

由于 k 已从可用值列表中有效删除并替换为未分配的 Nth 值,因此永远不会再次选择该值。

     public static   int [] getRandom(int size, int range) {
         Random r = new Random();
         int[] ret = new int[size];
         // initialize number pool
         int[] nums = IntStream.range(0,range).toArray();

         for (int i = 0; i < size; i++) {
            int k = r.nextInt(range);
            ret[i] = nums[k];
            range--;
            nums[k] = nums[range];
         }
         return ret;
       }

为了对此进行测试,我推荐以下内容。该集合被填充只是为了表明没有重复项。具有讽刺意味的是,填充集合来证明一个点比实际生成值需要更多的时间。

        int[] v = getRandom(10_000_000, 10_000_000);
        System.out.println("Done! Filling set");
        Set<Integer> set = Arrays.stream(v)
                 .boxed()
                 .collect(Collectors.toCollection(LinkedHashSet::new));
        System.out.printf("%,d%n",set.size());
        System.out.printf("%,d%n",v.length);

版画

Done! Filling set.
10,000,000
10,000,000