从地图中选择一个随机键和值



这是一个看似微不足道的编码任务,我似乎无法找到优雅的解决方案。也许这是一个星期天的下午"愚蠢"的事情,但我只是没有看到它。

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

  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"]

不需要任何强大的随机性或所选值的任何偶数分布。我只是为我为工作中编写的新功能编写的性能基准生成一些测试数据而需要进行粗略的近似。

谢谢

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

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]

您的问题是其他一些的重复。从重复的链接中,它可能是独一无二的,因为您需要以嵌套的方式找到两次集合的随机元素。您可以从地图的输入集中获取随机地图条目,抓住该键,然后从该条目的值中获取一个随机元素,该元素本身就是另一组。

为此,如果我们创建一个可以在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

最新更新