在Java中创建一个随机映射的映射

时间:2014-08-31 15:01:21

标签: java random map

我希望表单中有Map

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

或者

0 -> 4
1 -> 0
2 -> 2
3 -> 3
4 -> 1

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

4 个答案:

答案 0 :(得分:2)

public static Map<Integer,Integer> bijectiveMap(int n) {
        List<Integer> values = new ArrayList<>(n);
        for (int i=0 ; i<n ; i++)
            values.add(i);
        Collections.shuffle(values);

        Map<Integer,Integer> result = new HashMap<>();
        for (int i=0 ; i<n ; i++)
            result.put(i,values.get(i));
        return result;
    }

n = 10的输出:

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

答案 1 :(得分:1)

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

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

答案 2 :(得分:1)

忘记Map。只需随机播放Array / ArrayList(使用a[i] = i初始化)。分发质量取决于您的随机算法。

答案 3 :(得分:0)

如果避免使用Collections.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;
}
  1. 创建适当大小的所有集合(这里的hashmap加载因子大约是20%,它会占用太多空间)。
  2. 在一个循环中随机播放和添加元素
  3. 由于没有订购keySet,因此无需从1到N
  4. 将Random作为瞬态静态,然后在某些情况下也会更快。
  5. 将Apache集合用于int和long,而不是用于Integer包装器

    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;
    }
    
  6. 我为List循环道歉,今天它太多了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;
    }