多个集合中的共同和独特元素

本周,我们将暂时中断较高级别的问题和技术文章,以解决我们中许多人可能面临的一些代码问题。 没什么花哨的或太辛苦的,但是有一天它可能会节省您15分钟的时间,偶尔回到基础上也很不错。

因此,让我们开始吧。 有时,您会发现需要确定一个集合中的哪些元素存在于另一个集合中,哪些是常见的和/或哪些不存在于另一个集合中。 阿帕奇百科全书集合CollectionUtils一些一些实用方法是有用的,尤其是路口 (),但这个帖子去有点超出了到计算集合的集合独特的元素,它总是很高兴坐下来的细节。 我们还将通过支持任意数量的集合(而不是像CollectionUtils那样仅支持两个集合)来使解决方案更加通用。 另外,事实是,并非所有人都选择或能够包含库只是为了获得几个有用的实用程序方法。

当仅处理两个集合时,这不是一个难题,但是并非所有开发人员都熟悉java.util.Collection定义的所有方法,因此这里是一些示例代码。 他们的关键是一起使用keepAllremoveAll方法来构建三个集合-通用,仅在集合A中存在,仅在B中存在。

Set<String> a = new HashSet<String>();
a.add("a");
a.add("a2");
a.add("common");

Set<String> b = new HashSet<String>();
b.add("b");
b.add("b2");
b.add("common");

Set<String> inAOnly = new HashSet<String>(a);
inAOnly.removeAll(b);
System.out.println("A Only: " + inAOnly );

Set<String> inBOnly = new HashSet<String>(b);
inBOnly .removeAll(a);
System.out.println("B Only: " + inBOnly );

Set<String> common = new HashSet<String>(a);
common.retainAll(b);
System.out.println("Common: " + common);

输出:

A Only: [a, a2]
B Only: [b, b2]
Common: [common1]

处理三个或更多集合
处理两个以上的集合时,这个问题有些棘手,但是可以很简单地以一种通用的方式解决,如下所示:

计算通用元素
计算公共元素很容易,即使有大量集合,此代码也将始终如一地执行。

public static void main(String[] args) {
   List<String> a = Arrays.asList("a", "b", "c");
   List<String> b = Arrays.asList("a", "b", "c", "d");
   List<String> c = Arrays.asList("d", "e", "f", "g");

   List<List<String>> lists = new ArrayList<List<String>>();
   lists.add(a);
   System.out.println("Common in A: " + getCommonElements(lists));

   lists.add(b);
   System.out.println("Common in A & B: " + getCommonElements(lists));

   lists.add(c);
   System.out.println("Common in A & B & C: " + getCommonElements(lists));

   lists.remove(a);
   System.out.println("Common in B & C: " + getCommonElements(lists));
}

public static <T> Set<T> getCommonElements(Collection<? extends Collection<T>> collections) {

    Set<T> common = new LinkedHashSet<T>();
    if (!collections.isEmpty()) {
       Iterator<? extends Collection<T>> iterator = collections.iterator();
       common.addAll(iterator.next());
       while (iterator.hasNext()) {
          common.retainAll(iterator.next());
       }
    }
    return common;
}

输出:

Common in A: [a, b, c]
Common in A & B: [a, b, c]
Common in A & B & C: []
Common in B & C: [d]

计算独特元素
计算唯一元素与计算通用元素一样简单。 请注意,此代码的性能将随着您添加大量集合而降低,尽管在大多数实际情况下都没有关系。 我猜想有一些方法可以优化它,但是由于我没有遇到问题,所以我没有打扰tryin。 正如克努斯(Knuth)著名的说法 :“我们应该忘记效率低下的问题,大约有97%的时间是这样:过早的优化是万恶之源”。

public static void main(String[] args) {
   List<String> a = Arrays.asList("a", "b", "c");
   List<String> b = Arrays.asList("a", "b", "c", "d");
   List<String> c = Arrays.asList("d", "e", "f", "g");

   List<List<String>> lists = new ArrayList<List<String>>();
   lists.add(a);
   System.out.println("Unique in A: " + getUniqueElements(lists));

   lists.add(b);
   System.out.println("Unique in A & B: " + getUniqueElements(lists));

   lists.add(c);
   System.out.println("Unique in A & B & C: " + getUniqueElements(lists));

   lists.remove(a);
   System.out.println("Unique in B & C: " + getUniqueElements(lists));
}

public static <T> List<Set<T>> getUniqueElements(Collection<? extends Collection<T>> collections) {

    List<Set<T>> allUniqueSets = new ArrayList<Set<T>>();
    for (Collection<T> collection : collections) {
       Set<T> unique = new LinkedHashSet<T>(collection);
       allUniqueSets.add(unique);
       for (Collection<T> otherCollection : collections) {
          if (collection != otherCollection) {
             unique.removeAll(otherCollection);
          }
       }
   }

    return allUniqueSets;
}

输出:

Unique in A: [[a, b, c]]
Unique in A & B: [[], [d]]
Unique in A & B & C: [[], [], [e, f, g]]
Unique in B & C: [[a, b, c], [e, f, g]]

这里的所有都是它的。 随意使用此代码,无论您喜欢什么,如果有任何改进或建议,请发表评论。 当我们分享知识和经验时,开发人员都将从中受益。

参考: 计算多个集合中的公共和唯一元素– Java和我们的JCG合作伙伴   Carfey软件博客博客上的Craig Flichel。


翻译自: https://www.javacodegeeks.com/2012/03/common-and-unique-elements-in-multiple.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值