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));
}
}