从地图中选择随机键和值?

时间:2017-06-25 15:00:16

标签: java

这是一个看似简单的编码任务,我似乎无法找到一个优雅的解决方案。也许这是一个星期天的下午' dumbness'事情,但我只是没有看到它。

我有一个代表一组名称的地图:

  1. Map<String, Set<String>> namesForGroup;

内容看起来像这样:

1 {"Grp1": {"a", "b", "c", "d"},
2 "Grp2": {"e", "f", "g", "h"}}

我喜欢的是从该地图中提取随机键值对的优雅方法。例如:

1 ["Grp1", "a"]
2 ["Grp1", "d"]
3 ["Grp2", "g"]
4 ["Grp1", "c"]
5 ["Grp2", "e"]

不要求任何强随机性或所选值的均匀分布。我只需要为性能基准生成一些测试数据就可以得到粗略的近似值。我正在编写一个我在工作中编写的新功能。

由于

2 个答案:

答案 0 :(得分:1)

从集合中获取随机元素比从列表中获取随机元素要复杂一些,但这是如何工作的:

private static String[] getRandomPair(Map<String, Set<String>> map) {
    Random random = new Random();

    String[] groups = map.keySet().toArray(new String[0]);
    String randomGroup = groups[random.nextInt(groups.length)];

    String[] names = map.get(randomGroup).toArray(new String[0]);
    String randomName = names[random.nextInt(names.length)];

    return new String[] { randomGroup, randomName };
}

样品使用:

public static void main(String[] args) {
    Map<String, Set<String>> namesForGroup = new HashMap<>();
    namesForGroup.put("Grp1", new HashSet<>(Arrays.asList("a", "b", "c", "d")));
    namesForGroup.put("Grp2", new HashSet<>(Arrays.asList("e", "f", "g", "h")));
    System.out.println(Arrays.toString(getRandomPair(namesForGroup)));
    System.out.println(Arrays.toString(getRandomPair(namesForGroup)));
    System.out.println(Arrays.toString(getRandomPair(namesForGroup)));
    System.out.println(Arrays.toString(getRandomPair(namesForGroup)));
}

打印例如:

[Grp2, e]
[Grp1, a]
[Grp2, e]
[Grp1, b]

答案 1 :(得分:0)

你的问题与其他几个问题相似。它可能是重复链接中唯一的,因为你需要以嵌套的方式找到一组的随机元素,两次。您可以从地图的条目集中获取随机地图条目,抓取该密钥,然后从该条目的值中获取一个随机元素,该值本身就是另一个集合。

要做到这一点,如果我们创建一个可以在Java Set中找到随机元素的辅助方法,它可能会有所帮助。这是必需的,因为集合本质上是无序的。我们不能只访问某个索引,因为没有一个索引(好吧,可能在TreeSet这可能有意义,但不是在常规Set中)。

public static < T > T getRandomSetEntry(Set<T> set) {
    int size = set.size();
    int item = new Random().nextInt(size);
    int i = 0;
    for (T obj : set) {
        if (i == item)
            return obj;
        i++;
    }

    return null;
}

public static void main(String args[]) {
    Map<String, Set<String>> namesForGroup = new HashMap<>();
    Set<String> set1 = new HashSet<>();
    set1.add("a");
    set1.add("b");
    set1.add("c");
    set1.add("d");
    Set<String> set2 = new HashSet<>();
    set2.add("e");
    set2.add("f");
    set2.add("g");
    set2.add("h");

    namesForGroup.put("Grp1", set1);
    namesForGroup.put("Grp2", set2);

    Set<Map.Entry<String, Set<String>>> set = namesForGroup.entrySet();
    Map.Entry<String, Set<String>> entry = getRandomSetEntry(set);
    String key = entry.getKey();
    String value = getRandomSetEntry(entry.getValue());
    System.out.println("key: " + key + ", value: " + value);
}

在这里演示:

Rextester