在Java中创建一个随机获取maps INT的映射

在Java中创建一个随机获取maps INT的映射,java,random,map,Java,Random,Map,我想要一张以下格式的地图: 0 -> 1 2 -> 0 1 -> 2 或 每个int都应该精确地映射到范围内的一个不同int。 我想给函数传递一个映射大小的int,然后返回一个映射对象。 实现此功能的好方法是什么?洗牌可以。可能不是最快的,但肯定是最干净的方式 public Map<Integer, Integer> getRandomMapping(int min, int max){ List<Integer> arr = new Arra

我想要一张以下格式的地图:

0 -> 1
2 -> 0
1 -> 2

每个int都应该精确地映射到范围内的一个不同int。 我想给函数传递一个映射大小的int,然后返回一个映射对象。
实现此功能的好方法是什么?

洗牌可以。可能不是最快的,但肯定是最干净的方式

public Map<Integer, Integer> getRandomMapping(int min, int max){
    List<Integer> arr = new ArrayList<Integer>();
    //Fill array in order
    for(int i = 0; i < max + 1; i++){
        arr.add(i + min);
    }
    //Shuffle
    Collections.shuffle(arr);

    //Read into map
    Map<Integer, Integer> m = new HashMap<Integer, Integer>();
    for(int i = 0; i < max + 1; i++){
        m.put(new Integer(i + min), arr.get(i));
    }

    return m;
}

洗牌可以。可能不是最快的,但肯定是最干净的方式

public Map<Integer, Integer> getRandomMapping(int min, int max){
    List<Integer> arr = new ArrayList<Integer>();
    //Fill array in order
    for(int i = 0; i < max + 1; i++){
        arr.add(i + min);
    }
    //Shuffle
    Collections.shuffle(arr);

    //Read into map
    Map<Integer, Integer> m = new HashMap<Integer, Integer>();
    for(int i = 0; i < max + 1; i++){
        m.put(new Integer(i + min), arr.get(i));
    }

    return m;
}
n=10时的输出:

{0=7,1=5,2=3,3=6,4=1,5=4,6=2,7=8,8=9,9=0}

n=10时的输出:


{0=7,1=5,2=3,3=6,4=1,5=4,6=2,7=8,8=9,9=0}

忘记地图吧。只需洗牌一个用[i]=i初始化的数组/数组列表。分发的质量取决于您的洗牌算法。

忘记地图吧。只需洗牌一个用[i]=i初始化的数组/数组列表。分发的质量取决于您的洗牌算法。

如果避免收集。洗牌。这里

public static Map<Integer, Integer> foo(final int size) {
    final Map<Integer, Integer> out = new HashMap<Integer, Integer>(size*5);
    final List<Integer> values = new ArrayList<Integer>(size);
    Random r = new Random();
    for (int i = 0; i < size; i++) {
        values.add(i, i);
    }
    for (int i = size; i > 0; i--) {
        out.put(new Integer(i), values.remove(r.nextInt(i)));
    }
    return out;
}
创建所有大小合适的集合hashmap这里的加载因子约为20%,这样会占用太多空间。 在一个循环中洗牌并添加元素 由于键集未排序,因此无需从1到N 将“随机”设置为瞬态静态,则在某些情况下速度也会更快。 将Apache集合用于int和long,而不是整数包装

final static transient Random r = new Random();
final public static Map<Integer, Integer> foo(final int size) {
    final Map<Integer, Integer> out = new HashMap<Integer, Integer>(size*5);
    final List<Integer> values = new ArrayList<Integer>(size);
    int i;

    for (i = 0; i < size; i++) {
        values.add(i, i);
    }
    for (; i > 0; i--) {
        out.put(new Integer(i), values.remove(r.nextInt(i)));
    }
    return out;
}
我为列表循环道歉,今天的std::vector太多了。快速解

final static transient Random rand = new Random();
final public static Map<Integer, Integer> foo(final int size) {
    final Map<Integer, Integer> out = new HashMap<Integer, Integer>(size*5);
    final Integer[] values = new Integer[size];
    int i, r;
    for (i = 0; i <size; i++) {
        values[i] = i;
    }
    for (; i > 0; i--) {
        r = rand.nextInt(i);
        out.put(i, values[r]);
        values[r] = values[i-1];
    }
    return out;
}

如果要避免集合,请使用shuffle。这里

public static Map<Integer, Integer> foo(final int size) {
    final Map<Integer, Integer> out = new HashMap<Integer, Integer>(size*5);
    final List<Integer> values = new ArrayList<Integer>(size);
    Random r = new Random();
    for (int i = 0; i < size; i++) {
        values.add(i, i);
    }
    for (int i = size; i > 0; i--) {
        out.put(new Integer(i), values.remove(r.nextInt(i)));
    }
    return out;
}
创建所有大小合适的集合hashmap这里的加载因子约为20%,这样会占用太多空间。 在一个循环中洗牌并添加元素 由于键集未排序,因此无需从1到N 将“随机”设置为瞬态静态,则在某些情况下速度也会更快。 将Apache集合用于int和long,而不是整数包装

final static transient Random r = new Random();
final public static Map<Integer, Integer> foo(final int size) {
    final Map<Integer, Integer> out = new HashMap<Integer, Integer>(size*5);
    final List<Integer> values = new ArrayList<Integer>(size);
    int i;

    for (i = 0; i < size; i++) {
        values.add(i, i);
    }
    for (; i > 0; i--) {
        out.put(new Integer(i), values.remove(r.nextInt(i)));
    }
    return out;
}
我为列表循环道歉,今天的std::vector太多了。快速解

final static transient Random rand = new Random();
final public static Map<Integer, Integer> foo(final int size) {
    final Map<Integer, Integer> out = new HashMap<Integer, Integer>(size*5);
    final Integer[] values = new Integer[size];
    int i, r;
    for (i = 0; i <size; i++) {
        values[i] = i;
    }
    for (; i > 0; i--) {
        r = rand.nextInt(i);
        out.put(i, values[r]);
        values[r] = values[i-1];
    }
    return out;
}

将数组设为0。。N、 然后将其洗牌,然后按从0到N的顺序放入映射。好吧,如果从一开始就知道大小的话。实现此功能最有效的方法是不使用Java。为什么?没有理由。请说明你的目标是什么。速度真实随机分布?好代码?否则你就得不到好的答案,可能会因为答案过于基于意见而被关闭。是否必须是地图?使用洗牌数组还不够吗?将数组设为0。。N、 然后将其洗牌,然后按从0到N的顺序放入映射。好吧,如果从一开始就知道大小的话。实现此功能最有效的方法是不使用Java。为什么?没有理由。请说明你的目标是什么。速度真实随机分布?好代码?否则你就得不到好的答案,可能会因为答案过于基于意见而被关闭。是否必须是地图?使用洗牌数组还不够吗?+1,数组/数组列表更容易使用。如果出于某种原因确实需要返回映射,您可以创建一个类来包装数组并实现映射接口。+1,数组/ArrayList更易于使用。如果出于某种原因确实需要返回一个映射,您可以创建一个类来包装数组并实现映射接口。您的实现,size=100_000:1557 ms,size=1_000:167130 ms。使用Collections.shuffle实现,size=100_000:95 ms,size=1_000:2934 ms。您说要快得多吗?删除值元素的成本非常高,而Collections.shuffle仅交换元素。无论如何问题解决了,我不想开始辩论。我想说的是,将元素删除到ArrayList是启用的,所以最后一个循环是^2,而Collections.shuffle是启用的。时期你自己试试!您的实现,size=100_000:1557 ms,size=1_000:167130 ms。使用Collections.shuffle实现,size=100_000:95 ms,size=1_000:2934 ms。您说快多了?删除值元素的成本非常高,而Collections.shuffle仅交换元素。无论如何问题解决了,我不想开始辩论。我想说的是,将元素删除到ArrayList是启用的,所以最后一个循环是^2,而Collections.shuffle是启用的。时期你自己试试!