美文网首页
Guava——Immutable Collections

Guava——Immutable Collections

作者: 爱吃菜的流浪狗 | 来源:发表于2019-01-02 14:51 被阅读0次

    不可变集合: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));

    }

    相关文章

      网友评论

          本文标题:Guava——Immutable Collections

          本文链接:https://www.haomeiwen.com/subject/jkyzlqtx.html