ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

guava源码阅读——collect.Sets类

2020-08-06 13:00:42  阅读:289  来源: 互联网

标签:set return collect 源码 set1 set2 guava final size


1.写在前面

在开始之前,说明一下该篇中重点在union、intersection、difference、filter的实现,对于Sets类中的其他方法如newHashSet、newConcurrentHashSet、newLinkedHashSet等方法等见名知意,不做介绍。

2.阅读内容

collect.Sets类

3.源码分析

3.1 union(final Set<? extends E> set1, final Set<? extends E> set2)方法

该方法时求两个set的并集,返回的是一个不可修改的视图

public static  SetView union(final Set set1, final Set set2) {
     //检查set1和set2是否为空
    checkNotNull(set1, "set1");
    checkNotNull(set2, "set2");
 
    return new SetView() {
      @Override
       //求并集的大小,并集的大小肯定是大于等于set1或set2的大小,这里以set1大小为基数,依次去set2取元素判断是否包含在set1,不是size+1
      public int size() { 
        int size = set1.size();
        for (E e : set2) {
          if (!set1.contains(e)) {
            size++;
          }
        }
        return size;
      }
 
      @Override
      //判断并集视图是否为空,需要满足set1和set2同时为空
      public boolean isEmpty() {
        return set1.isEmpty() && set2.isEmpty();
      }
 
      @Override
      //迭代
      public UnmodifiableIterator iterator() {
        return new AbstractIterator() {
          final Iterator itr1 = set1.iterator();
          final Iterator itr2 = set2.iterator();
 
          @Override
          //迭代其中的一整个set(这里是set1),然后再去另一个set中迭代不重复的元素
          protected E computeNext() {
            if (itr1.hasNext()) {
              return itr1.next();
            }
            while (itr2.hasNext()) {
              E e = itr2.next();
              if (!set1.contains(e)) {
                return e;
              }
            }
            return endOfData();
          }
        };
      }
      ......
      @Override
      //判断是否包含一个元素,如果set1和set2任意一个包含,即包含
      public boolean contains(Object object) {
        return set1.contains(object) || set2.contains(object);
      }
 
      @Override
      //将并集结果放入一个set,利用set元素不重复这条特性,直接添加即可
      public > S copyInto(S set) {
        set.addAll(set1);
        set.addAll(set2);
        return set;
      }
 
      @Override
      //使用了建造者模式添加,返回一个不可变的set
      public ImmutableSet immutableCopy() {
        return new ImmutableSet.Builder().addAll(set1).addAll(set2).build();
      }
    };
  }
View Code

 

3.2 intersection(final Set<E> set1, final Set<?> set2)方法

该方法是求两个set的交集,返回的仍是一个不可修改的视图

public static  SetView intersection(final Set set1, final Set set2) {
    //依旧是检查set
   checkNotNull(set1, "set1");
   checkNotNull(set2, "set2");
 
   return new SetView() {
     @Override
     public UnmodifiableIterator iterator() {
       return new AbstractIterator() {
         final Iterator itr = set1.iterator();
 
         @Override
         //迭代set1,看set1中的每一个元素是否在set2中存在
         protected E computeNext() {
           while (itr.hasNext()) {
             E e = itr.next();
             if (set2.contains(e)) {
               return e;
             }
           }
           return endOfData();
         }
       };
     }
     ......
     @Override
     //迭代set1,看set1中的每一个元素是否包含在set2中,是的话size+1
     public int size() {
       int size = 0;
       for (E e : set1) {
         if (set2.contains(e)) {
           size++;
         }
       }
       return size;
     }
     //其余方法道理一致
    ......
   };
 }
View Code

 

3.3 difference(final Set<E> set1, final Set<?> set2)方法

该方法是求两个set的差集,返回一个不可修改的视图。
但是需要注意的一点是:如果该方法只会返回在set1中的值,不会返回set2中的,如果想要的差集结果希望是set1中的和set2中的,应该使用symmetricDifference方法。

public static  SetView difference(final Set set1, final Set set2) {
   checkNotNull(set1, "set1"); //检查
   checkNotNull(set2, "set2");
 
   return new SetView() {
     @Override
     public UnmodifiableIterator iterator() {
       return new AbstractIterator() {
         final Iterator itr = set1.iterator();
 
         @Override
         //迭代set1,与set2比较,不包含返回,只看set1中的结果
         protected E computeNext() {
           while (itr.hasNext()) {
             E e = itr.next();
             if (!set2.contains(e)) {
               return e;
             }
           }
           return endOfData();
         }
       };
     }
     ......
     @Override
     //也是只看set1中的结果
     public int size() {
       int size = 0;
       for (E e : set1) {
         if (!set2.contains(e)) {
           size++;
         }
       }
       return size;
     }
     ......
   };
 }
View Code

 

3.4 filter方法

根据传入的set和过滤规则predicate,返回过滤后的set。

public static  SortedSet filter(SortedSet unfiltered, Predicate predicate) {
    //根据传入的set类型选择过滤的逻辑方法
   if (unfiltered instanceof FilteredSet) {
     // Support clear(), removeAll(), and retainAll() when filtering a filtered
     // collection.
     FilteredSet filtered = (FilteredSet) unfiltered;
     Predicate combinedPredicate = Predicates.and(filtered.predicate, predicate);
     return new FilteredSortedSet((SortedSet) filtered.unfiltered, combinedPredicate);
   }
   return new FilteredSortedSet(checkNotNull(unfiltered), checkNotNull(predicate));
 }
View Code

标签:set,return,collect,源码,set1,set2,guava,final,size
来源: https://www.cnblogs.com/ericz2j/p/13445622.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有