0

我需要加入两个Collection<String>,获取 n 个随机元素并将它们从存储它们的原始集合中删除。

要加入集合,我考虑迭代它们并存储在自定义地图结构中,以便:

  1. 存储相同的密钥 n 次
  2. 获取原始集合。

有没有一种简单的方法可以做到这一点?

你能帮助我吗?

4

3 回答 3

1

这个怎么样:

Collection<String> collection1 = new ArrayList<String>();
Collection<String> collection2 = new ArrayList<String>();

List<String> allElements = new ArrayList<String>(collection1);
allElements.addAll(collection2);
Collections.shuffle(allElements);

Random random = new Random();
int n = 10;
List<String> randomResults = new ArrayList<String>(n);
for (int i = 0; i < n && !allElements.isEmpty(); i++) {
  String randomElement = allElements.remove(random.nextInt(allElements.size()));
  randomResults.add(randomElement);
}

collection1.removeAll(randomResults);
collection2.removeAll(randomResults);
于 2013-02-20T15:27:31.940 回答
0

以下内容对您有用吗?

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

import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;

public class Combiner {
    private static final Random rnd = new Random();

    public static void main(String[] args) {
        Collection<String> boys = Sets.newHashSet("James", "John", "andrew",
                "peter");
        Collection<String> girls = Sets.newHashSet("mary", "jane", "rose",
                "danny");

        // Combine the two
        Iterable<String> humans = Iterables.concat(boys, girls);

        // Get n Random elements from the mix
        int n = 2;
        Collection<String> removed = randomSample4(humans, n);

        // Remove from the original Collections
        Iterables.removeAll(boys, removed);
        Iterables.removeAll(girls, removed);

        // or even
        boys.removeAll(removed);
        girls.removeAll(removed);

        // And now we check if all is well
        System.out.println(boys);
        System.out.println(girls);

    }

    public static <T> Collection<T> randomSample4(Iterable<T> humans, int m) {
        List<T> sample = Lists.newArrayList(humans);
        Set<T> res = new HashSet<T>(m);
        int n = sample.size();
        for (int i = n - m; i < n; i++) {
            int pos = rnd.nextInt(i + 1);
            T item = sample.get(pos);
            if (res.contains(item))
                res.add(sample.get(i));
            else
                res.add(item);
        }
        return res;
    }
}

randomSample4 方法已复制自此博客

于 2013-02-20T15:04:01.080 回答
0

有趣的是,您想为此使用地图。我建议使用MultiMapGoogle's Guava例如)。它允许您持有一个键,然后是一个Collection值,所有这些都属于该键。因此,您将只有两个键(对应于您的原始键Collections)。

另一种解决方案是将全部添加Collections到第三个 aCollection中(有一种addAll(Collection c)方法可用)。如果没有重复值,您可以在迭代时检查第三个集合中的某个项目是否属于其他两个集合中的任何一个。

这些是实现您提出的任何问题的基本方法,但值得一试。

希望这些指针对您有所帮助!

于 2013-02-20T14:15:06.270 回答