Guava-ImmutableList

前言

分析完ImmutableSet后,接着分析ImmutableList,从字面上可知其是不可变的列表,可根据索引获取对应项,由于其在创建后不可变,底层可以使用数组来存储,这样会访问效率。

ImmutableList

ImmutableList类实现了ImmutableCollection接口和List接口,可以使用of方法或者builder配合build方法创建ImmutableList实例。

示例


package com.hust.grid.leesf.guavalearning;

import com.google.common.collect.ImmutableList;

public class ImmutableListTest {
    public static void main(String[] args) {
        ImmutableList<String> strings = ImmutableList.of("dyd", "leesf", "ld");
        System.out.println(strings);

        strings = ImmutableList.<String>builder().add("dyd").add("leesf").add("ld").build();
        System.out.println(strings);
    }
}


运行结果:

[dyd, leesf, ld]
[dyd, leesf, ld]

示例展示了通过ofbuilderbuild方法构建ImmutableList对象。

construct方法

调用of方法会调用ImmutableListconstruct方法,其源码如下


  private static <E> ImmutableList<E> construct(Object... elements) {
    for (int i = 0; i < elements.length; i++) {
      ObjectArrays.checkElementNotNull(elements[i], i);
    }
    return new RegularImmutableList<E>(elements);
  }

首先会检查传入的数组是否有值为空,若为空,则会抛出异常,否则,调用RegularImmutableList构造函数,其中,RegularImmutableList继承ImmutableList类,其内部使用数组和偏移值来保存具体的值。

builder方法

调用builder方法会生成新的Builder实例,Builder类的源码大致如下


public static final class Builder<E> extends ImmutableCollection.Builder<E> {
	private Object[] contents;
	private int size;
}


构造函数会生成默认大小的数组,并设置size = 0size用于指示已经添加了多少个元素。

add方法

当使用builder方法返回Builder对象后,可使用add方法添加元素,其源码如下


    @Override public Builder<E> add(E element) {
      checkNotNull(element);
      ensureCapacity(size + 1);
      contents[size++] = element;
      return this;
    }

可以看到首先检查传入的元素是否为空,然后保证新添加元素后保证数组不会溢出。

build方法

当使用add方法添加完所有的元素后,需要调用build方法完成ImmutableList的构造,其源码如下


    @Override public ImmutableList<E> build() {
      switch (size) {
        case 0:
          return of();
        case 1:
          @SuppressWarnings("unchecked") // guaranteed to be an E
          E singleElement = (E) contents[0];
          return of(singleElement);
        default:
          if (size == contents.length) {
            // no need to copy; any further add operations on the builder will copy the buffer
            return new RegularImmutableList<E>(contents);
          } else {
            return new RegularImmutableList<E>(ObjectArrays.arraysCopyOf(contents, size));
          }
      }
    }

可以看到其会根据添加的元素个数来生成对应的List

总结

ImmutableList类在完成构造后便不可再添加元素,所有修改集合的操作均会抛出异常,其使用和源码相对简单。