1. 程式人生 > >Guava原始碼解析十一:Sets原始碼解析

Guava原始碼解析十一:Sets原始碼解析

功能函式

建立一個不可變的set

1.ImmutableSet<E> immutableEnumSet(E anElement, E... otherElements)

2.ImmutableSet<E> immutableEnumSet(Iterable<E> elements)

建立一個HashSet

1.HashSet<E> newHashSet()

2.HashSet<E> newHashSet(E... elements)

3.HashSet<E> newHashSetWithExpectedSize(int expectedSize)

4.HashSet<E> newHashSet(Iterable<? extends E> elements)

5.HashSet<E> newHashSet(Iterator<? extends E> elements)

建立一個執行緒安全的Set

1.Set<E> newConcurrentHashSet()

2.Set<E> newConcurrentHashSet(Iterable<? extends E> elements)

建立一個LinkedHashMap

1.LinkedHashSet<E> newLinkedHashSet()

2.LinkedHashSet<E> newLinkedHashSetWithExpectedSize(int expectedSize)

3.LinkedHashSet<E> newLinkedHashSet(Iterable<? extends E> elements)

建立一個TreeSet

1.TreeSet<E> newTreeSet()

2.TreeSet<E> newTreeSet(Iterable<? extends E> elements)

3.TreeSet<E> newTreeSet(Comparator<? super E> comparator)

建立一個IdentityHashSet

1.Set<E> newIdentityHashSet()

建立一個CopyOnWriteArraySet

1.CopyOnWriteArraySet<E> newCopyOnWriteArraySet()

2.CopyOnWriteArraySet<E> newCopyOnWriteArraySet(Iterable<? extends E> elements)

建立一個EnumSet

1.EnumSet<E> newEnumSet(Iterable<E> iterable, Class<E> elementType)

2.EnumSet<E> complementOf(Collection<E> collection)

3.EnumSet<E> complementOf(Collection<E> collection, Class<E> type)

4.EnumSet<E> makeComplementByHand(Collection<E> collection, Class<E> type)

根據一個Map建立一個Set

1.Set<E> newSetFromMap(Map<E, Boolean> map)

以兩個Set的並集作為檢視

1.Sets.SetView<E> union(final Set<? extends E> set1, final Set<? extends E> set2)

以兩個Set的交集作為檢視

1.Sets.SetView<E> intersection(final Set<E> set1, final Set<?> set2)

以兩個Set的互不重疊的部分作為檢視

1.Sets.SetView<E> difference(final Set<E> set1, final Set<?> set2)

以兩個Set的對稱部分作為檢視

1.Sets.SetView<E> symmetricDifference(Set<? extends E> set1, Set<? extends E> set2)

過濾Set

1.filter(Set<E> unfiltered, Predicate<? super E> predicate)

2.SortedSet<E> filter(SortedSet<E> unfiltered, Predicate<? super E> predicate)

3.SortedSet<E> filterSortedIgnoreNavigable(SortedSet<E> unfiltered, Predicate<? super E> predicate)

4.NavigableSet<E> filter(NavigableSet<E> unfiltered, Predicate<? super E> predicate)

獲取兩個Set集合的笛卡爾積

1.Set<List<B>> cartesianProduct(List<? extends Set<? extends B>> sets)

2.Set<List<B>> cartesianProduct(Set<? extends B>... sets)

 

建立一個不可變的Set

1.根據傳入的引數,建立一個不可變的Set

public static <E extends Enum<E>> ImmutableSet<E> immutableEnumSet(E anElement, E... otherElements) {
    return ImmutableEnumSet.asImmutable(EnumSet.of(anElement, otherElements));
}

EnumSet.of方法是將anElement和otherElements合併成一個EnumSet,原始碼為:

public static <E extends Enum<E>> EnumSet<E> of(E first, E... rest) {
    EnumSet<E> result = noneOf(first.getDeclaringClass());
    //將第一個引數先插入到EnumSet中
    result.add(first);
    //在將傳入的陣列全部插入到EnumSet中
    for (E e : rest)
        result.add(e);
    return result;
}

最後使用ImmutableEnumSet.asImmutable函式將EnumSet轉為ImmutableSet

 

2.根據一個集合建立一個不可變的Set

public static <E extends Enum<E>> ImmutableSet<E> immutableEnumSet(Iterable<E> elements) {
    //如果是一個ImmutableEnumSet,則直接轉換為ImmutableEnumSet
    if(elements instanceof ImmutableEnumSet) {
        return (ImmutableEnumSet)elements;
    } else if(elements instanceof Collection) {
        //如果是一個Collection且不為空則,直接使用ImmutableEnumSet.asImmutable方法轉化為ImmutableEnumSet
        Collection itr1 = (Collection)elements;
        return itr1.isEmpty()?ImmutableSet.of():ImmutableEnumSet.asImmutable(EnumSet.copyOf(itr1));
    } else {
        //其他型別,則獲取他的迭代器,然後製作一個ImmutableEnumSet
        Iterator itr = elements.iterator();
        if(itr.hasNext()) {
            EnumSet enumSet = EnumSet.of((Enum)itr.next());
            Iterators.addAll(enumSet, itr);
            return ImmutableEnumSet.asImmutable(enumSet);
        } else {
            return ImmutableSet.of();
        }
    }
}

 

建立一個HashSet

1.直接new一個HashSet

public static <E> HashSet<E> newHashSet() {
    return new HashSet();
}

2.傳入一個數組,返回一個HashSet

public static <E> HashSet<E> newHashSet(E... elements) {
    //建立一個期望大小為elements.length的HashSet
    HashSet set = newHashSetWithExpectedSize(elements.length);
    //將陣列中的元素,全部賦值給新的HashSet
    Collections.addAll(set, elements);
    return set;
}

3.建立一個期望大小的HashSet

public static <E> HashSet<E> newHashSetWithExpectedSize(int expectedSize) {
    //建立一個HashSet,大小為Maps.capacity方法計算後的值,這個方法最終返回原值的4/3
    return new HashSet(Maps.capacity(expectedSize));
}

4.根據傳入的集合建立一個HashSet

public static <E> HashSet<E> newHashSet(Iterable<? extends E> elements) {
    return elements instanceof Collection?new HashSet(Collections2.cast(elements)):newHashSet((Iterator)elements.iterator());
}

5.根據傳入的迭代器建立一個HashSet

public static <E> HashSet<E> newHashSet(Iterator<? extends E> elements) {
    //建立一個HashSet
    HashSet set = newHashSet();
    //使用Guava中的Iterators.addAll方法將迭代器中的元素新增到set中
    Iterators.addAll(set, elements);
    return set;
}

 

建立一個執行緒安全的Set

1.使用ConcurrentHashMap建立一個Set

public static <E> Set<E> newConcurrentHashSet() {
    //建立一個ConcurrentHashMap,使用newSetFromMap方法將ConcurrentHashMap的值轉為Set
    return newSetFromMap(new ConcurrentHashMap());
}

2.使用傳入的集合建立一個執行緒安全的Set

public static <E> Set<E> newConcurrentHashSet(Iterable<? extends E> elements) {
    //建立一個ConcurrentHashSet
    Set set = newConcurrentHashSet();
    //使用Guava中的Iterables.addAll方法將集合elements中的元素新增到set中
    Iterables.addAll(set, elements);
    return set;
}

建立一個LinkedHashSet

1.直接建立一個LinkedHashSet

public static <E> LinkedHashSet<E> newLinkedHashSet() {
    return new LinkedHashSet();
}

2.建立一個期望大小的LinkedHashSet

public static <E> LinkedHashSet<E> newLinkedHashSetWithExpectedSize(int expectedSize) {
    //返回一個LinkedHashSet,大小為expectedSize的4/3
    return new LinkedHashSet(Maps.capacity(expectedSize));
}

3.根據傳入的集合,返回一個LinkedHashSet

public static <E> LinkedHashSet<E> newLinkedHashSet(Iterable<? extends E> elements) {
    //如果是一個Collection型別,則直接建立LinkedHashSet,並將集合中的值賦值給新的LinkedHashSet
    if(elements instanceof Collection) {
        return new LinkedHashSet(Collections2.cast(elements));
    } else {
        LinkedHashSet set = newLinkedHashSet();
        Iterables.addAll(set, elements);
        return set;
    }
}

 

建立一個TreeSet

1.直接建立一個TreeSet

public static <E extends Comparable> TreeSet<E> newTreeSet() {
    return new TreeSet();
}

2.傳入一個集合,返回一個TreeSet,並將集合中的元素賦值給TreeSet

public static <E extends Comparable> TreeSet<E> newTreeSet(Iterable<? extends E> elements) {
    //建立一個TreeSet
    TreeSet set = newTreeSet();
    //將集合中的元素賦值給TreeSet
    Iterables.addAll(set, elements);
    return set;
}

3.傳入一個Comparator,根據Comparator的規則建立一個TreeSet

public static <E> TreeSet<E> newTreeSet(Comparator<? super E> comparator) {
    return new TreeSet((Comparator)Preconditions.checkNotNull(comparator));
}

建立一個IdentityHashSet

1.根據Maps.newIdentityHashMap()和Sets.newSetFromMap兩個方法建立一個IdentityHashSet

public static <E> Set<E> newIdentityHashSet() {
    //使用Maps.newIdentityHashMap()方法建立一個IdentityHashMap,然後使用newSetFromMap方法將Map轉為Set
    return newSetFromMap(Maps.newIdentityHashMap());
}

建立一個CopyOnWriteArraySet

1.直接建立一個CopyOnWriteArraySet

public static <E> CopyOnWriteArraySet<E> newCopyOnWriteArraySet() {
    return new CopyOnWriteArraySet();
}

2.根據傳入的集合建立一個CopyOnWriteArraySet,並將集合中的資料賦值給CopyOnWriteArraySet

public static <E> CopyOnWriteArraySet<E> newCopyOnWriteArraySet(Iterable<? extends E> elements) {
    //如果是一個Collection,直接將其轉為Collection,如果不是則使用Lists建立一個List
    Object elementsCollection = elements instanceof Collection?Collections2.cast(elements):Lists.newArrayList(elements);
    return new CopyOnWriteArraySet((Collection)elementsCollection);
}

 

建立一個EnumSet

1.根據傳入的集合和一個型別,返回一個EnumSet

public static <E extends Enum<E>> EnumSet<E> newEnumSet(Iterable<E> iterable, Class<E> elementType) {
    //根據傳入的型別,建立一個set
    EnumSet set = EnumSet.noneOf(elementType);
    //將集合中的元素新增到set中
    Iterables.addAll(set, iterable);
    return set;
}

2.傳入一個集合,返回一個EnumSet

public static <E extends Enum<E>> EnumSet<E> complementOf(Collection<E> collection) {
    if(collection instanceof EnumSet) {
        return EnumSet.complementOf((EnumSet)collection);
    } else {
        Preconditions.checkArgument(!collection.isEmpty(), "collection is empty; use the other version of this method");
        Class type = ((Enum)collection.iterator().next()).getDeclaringClass();
        return makeComplementByHand(collection, type);
    }
}

根據一個Map建立一個Set

1.根據Map建立一個Set

public static <E> Set<E> newSetFromMap(Map<E, Boolean> map) {
    return Platform.newSetFromMap(map);
}

可以看到這個方法實際呼叫了Platform.newSetFromMap方法,一層一層往上追,最終可以看到,實際上使用的是Collections.SetFromMap類:

private static class SetFromMap<E> extends AbstractSet<E> implements Set<E>, Serializable{
    private final Map<E, Boolean> m;  // The backing map
    private transient Set<E> s;       // Its keySet
    SetFromMap(Map<E, Boolean> map) {
        if (!map.isEmpty())
            throw new IllegalArgumentException("Map is non-empty");
        m = map;
        s = map.keySet();
    }
}

其實就是將map中的key集合作為一個Set了

 

以兩個Set的互不重疊的部分作為檢視

1.傳入兩個Set,返回一個兩個set1中不包含set2中的元素

public static <E> Sets.SetView<E> difference(final Set<E> set1, final Set<?> set2) {
    Preconditions.checkNotNull(set1, "set1");
    Preconditions.checkNotNull(set2, "set2");
    //建立一個過濾規則(規則為,不能包含set2中的元素)
    final Predicate notInSet2 = Predicates.not(Predicates.in(set2));
    return new Sets.SetView(null) {
        //重寫iterator,使用Iterators.filter過濾出不含set2元素的一個迭代器
        public Iterator<E> iterator() {
            return Iterators.filter(set1.iterator(), notInSet2);
        }
        //根據最終返回的迭代器計算長度
        public int size() {
            return Iterators.size(this.iterator());
        }
        //如果set1和set2中全部相等,就為空
        public boolean isEmpty() {
            return set2.containsAll(set1);
        }
        public boolean contains(Object element) {
            return set1.contains(element) && !set2.contains(element);
        }
    };
}

 

以兩個Set的並集作為檢視

public static <E> Sets.SetView<E> union(final Set<? extends E> set1, final Set<? extends E> set2) {
    Preconditions.checkNotNull(set1, "set1");
    Preconditions.checkNotNull(set2, "set2");
    //獲取set2,中不包含set1的所有元素
    final Sets.SetView set2minus1 = difference(set2, set1);
    return new Sets.SetView(null) {
        //獲取set1的全部長度和set2minus1檢視的長度
        public int size() {
            return set1.size() + set2minus1.size();
        }
        public boolean isEmpty() {
            return set1.isEmpty() && set2.isEmpty();
        }
        public Iterator<E> iterator() {
            return Iterators.unmodifiableIterator(Iterators.concat(set1.iterator(), set2minus1.iterator()));
        }
        public boolean contains(Object object) {
            return set1.contains(object) || set2.contains(object);
        }
        //返回所有元素
        public <S extends Set<E>> S copyInto(S set) {
            set.addAll(set1);
            set.addAll(set2);
            return set;
        }
        public ImmutableSet<E> immutableCopy() {
            return (new Builder()).addAll(set1).addAll(set2).build();
        }
    };
}

 

以兩個Set的交集作為檢視

public static <E> Sets.SetView<E> intersection(final Set<E> set1, final Set<?> set2) {
    Preconditions.checkNotNull(set1, "set1");
    Preconditions.checkNotNull(set2, "set2");
    //建立一個過濾規則(規則為:全部set2元素)
    final Predicate inSet2 = Predicates.in(set2);
    return new Sets.SetView(null) {
        //返回set1中包含set2中的所有元素
        public Iterator<E> iterator() {
            return Iterators.filter(set1.iterator(), inSet2);
        }
        //根據計算出的迭代器計算長度
        public int size() {
            return Iterators.size(this.iterator());
        }
        //根據迭代器判斷是否為空
        public boolean isEmpty() {
            return !this.iterator().hasNext();
        }
        public boolean contains(Object object) {
            return set1.contains(object) && set2.contains(object);
        }
        public boolean containsAll(Collection<?> collection) {
            return set1.containsAll(collection) && set2.containsAll(collection);
        }
    };
}

 

以兩個Set的對稱部分作為檢視

1.傳入兩個Set,返回兩個Set的對稱檢視

public static <E> Sets.SetView<E> symmetricDifference(Set<? extends E> set1, Set<? extends E> set2) {
    Preconditions.checkNotNull(set1, "set1");
    Preconditions.checkNotNull(set2, "set2");
    return difference(union(set1, set2), intersection(set1, set2));
}

 

過濾Set

Set的過濾和Maps中實現的各種過濾都是大同小異。

1.傳入一個Set和一個過濾規則,返回一個過濾後的Set

public static <E> Set<E> filter(Set<E> unfiltered, Predicate<? super E> predicate) {
    //如果傳入的Set為SortedSet型別,使用傳入SortedSet的方法進行處理
    if(unfiltered instanceof SortedSet) {
        return filter((SortedSet)((SortedSet)unfiltered), predicate);
    } else if(unfiltered instanceof Sets.FilteredSet) {
        Sets.FilteredSet filtered = (Sets.FilteredSet)unfiltered;
        Predicate combinedPredicate = Predicates.and(filtered.predicate, predicate);
        return new Sets.FilteredSet((Set)filtered.unfiltered, combinedPredicate);
    } else {
        return new Sets.FilteredSet((Set)Preconditions.checkNotNull(unfiltered), (Predicate)Preconditions.checkNotNull(predicate));
    }
}