Guava——Immutable Collections
不可变集合:ImmutableSet
public static final ImmutableSet<String> COLOR_NAMES = ImmutableSet.of(
"red",
"orange",
"yellow",
"green",
"blue",
"purple");
class Foo {
final ImmutableSet<Bar> bars;
Foo(Set<Bar> bars) {
this.bars = ImmutableSet.copyOf(bars); // defensive copy!
}
}
对不可靠的客户代码库来说,它使用安全,可以在未受信任的类库中安全的使用这些对象
线程安全的:immutable对象在多线程下安全,没有竞态条件
不需要支持可变性, 可以尽量节省空间和时间的开销. 所有的不可变集合实现都比可变集合更加有效的利用内存 (analysis)
可以被使用为一个常量,并且期望在未来也是保持不变的
构造方法: 都是采用静态方法
ImmutableSet.of() 来创建,参数可以有多个。当参数多余1个时会调用construct方法。
public static <E> ImmutableSet<E> of() {
return EmptyImmutableSet.INSTANCE;
}
public static <E> ImmutableSet<E> of(E element) {
return new SingletonImmutableSet(element);
}
public static <E> ImmutableSet<E> of(E e1, E e2) {
return construct(2, e1, e2);
}
public static <E> ImmutableSet<E> of(E e1, E e2, E e3) {
return construct(3, e1, e2, e3);
}
public static <E> ImmutableSet<E> of(E e1, E e2, E e3, E e4) {
return construct(4, e1, e2, e3, e4);
}
public static <E> ImmutableSet<E> of(E e1, E e2, E e3, E e4, E e5) {
return construct(5, e1, e2, e3, e4, e5);
}
public static <E> ImmutableSet<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E... others) {
int paramCount = true;
Object[] elements = new Object[6 + others.length];
elements[0] = e1;
elements[1] = e2;
elements[2] = e3;
elements[3] = e4;
elements[4] = e5;
elements[5] = e6;
System.arraycopy(others, 0, elements, 6, others.length);
return construct(elements.length, elements);
}
construct
当元素超过1个时调用默认方法。
private static <E> ImmutableSet<E> construct(int n, Object... elements) {
switch(n) {
case 0:
return of();
case 1:
E elem = elements[0];
return of(elem);
default:
int tableSize = chooseTableSize(n);
Object[] table = new Object[tableSize]; //创建一个Object的数组
int mask = tableSize - 1;
int hashCode = 0;
int uniques = 0;
int i = 0;
for(; i < n; ++i) {
Object element = ObjectArrays.checkElementNotNull(elements[i], i);
int hash = element.hashCode();
int j = Hashing.smear(hash);
while(true) {
int index = j & mask;
Object value = table[index];
if (value == null) {
elements[uniques++] = element;
table[index] = element;
hashCode += hash;
break;
}
if (value.equals(element)) {
break;
}
++j;
}
}
Arrays.fill(elements, uniques, n, (Object)null);
if (uniques == 1) {
E element = elements[0];
return new SingletonImmutableSet(element, hashCode);
} else if (tableSize != chooseTableSize(uniques)) {
return construct(uniques, elements);
} else {
Object[] uniqueElements = uniques < elements.length ? ObjectArrays.arraysCopyOf(elements, uniques) : elements;
return new RegularImmutableSet(uniqueElements, hashCode, table, mask);
}
}
}
会根据n确定参数setSzie的大小,当超出1073741824 会报错。
static int chooseTableSize(int setSize) {
if (setSize >= 751619276) {
Preconditions.checkArgument(setSize < 1073741824, "collection too large");
return 1073741824;
} else {
int tableSize;
for(tableSize = Integer.highestOneBit(setSize - 1) << 1; (double)tableSize * 0.7D < (double)setSize; tableSize <<= 1) {
;
}
return tableSize;
}
}
复制
public static <E> ImmutableSet<E> copyOf(E[] elements) {
switch(elements.length) {
case 0:
return of();
case 1:
return of(elements[0]);
default:
return construct(elements.length, (Object[])elements.clone());//并不是对elements的更改 而是克隆
}
}
//还是会调用of()函数创建
public static ImmutableSet copyOf(Iterable
return elements instanceof Collection ? copyOf((Collection)elements) : copyOf(elements.iterator());
}
public static ImmutableSet copyOf(Iterator
if (!elements.hasNext()) {
return of();
} else {
E first = elements.next();
return !elements.hasNext() ? of(first) : (new ImmutableSet.Builder()).add(first).addAll(elements).build();
}
}
public static ImmutableSet copyOf(Collection
if (elements instanceof ImmutableSet && !(elements instanceof ImmutableSortedSet)) {
ImmutableSet<E> set = (ImmutableSet)elements;
if (!set.isPartialView()) {
return set;
}
} else if (elements instanceof EnumSet) {
return copyOfEnumSet((EnumSet)elements);
}
Object[] array = elements.toArray();
return construct(array.length, array);
}
private static
return ImmutableEnumSet.asImmutable(EnumSet.copyOf(enumSet));
}