今天看代码发现很多地方都用到ImmutableMap。
ImmutableMap.of("id", record.getId(), "force",force)
源码如下:
public static < K , V > ImmutableMap < K , V > of ( K k1 , V v1 , K k2 , V v2 ) {
public static < K , V > ImmutableMap < K , V > of ( K k1 , V v1 , K k2 , V v2 ) {
return RegularImmutableMap.fromEntries(entryOf(k1, v1), entryOf(k2, v2));
}
会根据传入的参数分对组装成entry,例如传入四个参数的,是组装成两个entry
RegularImmutableMap<K, V>(entryOf(k1, v1), entryOf(k2, v2));
而Immutable.of()传入的参数最多是十个,也就是只能有5个entry。
public static <K, V> ImmutableMap<K, V> of( K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) { return new RegularImmutableMap<K, V>(entryOf(k1, v1), entryOf(k2, v2), entryOf(k3, v3), entryOf(k4, v4), entryOf(k5, v5)); }
之后会调用不确定参数的接口,确定要新建map的大小,
RegularImmutableMap(TerminalEntry<?, ?>... theEntries) { this(theEntries.length, theEntries); }
传输map的大小和entry的内容,新建一个ImmutableMapEnrty[size],是一个存放map的数组,会根据size的大小循环保存到table和entries中。entries是按照插入顺序保存的数组,table则是链表的数组。接口中会有是否要对table扩容的判断。
// entries in insertion order private final transient Entry<K, V>[] entries; // array of linked lists of entries private final transient ImmutableMapEntry<K, V>[] table;
何为Immutable对象?
如果一个对象实例不能被更改就是一个Immutable的对象,JavaSDK提供的大量对象中,比如String都是Immutable的。
如何使用Immutable对象?
按照Effective Java,需要满足以下原则:
~保证类不能继承
~移掉所有setter/update等修改对象实例的操作
~保证所有的field都是private和final的
什么是immutable对象呢?
immutable objects就是那些一旦被创建,他们的状态就不能被改变的objects,每次对他们的改变都是产生了新的immutabl object,而mutable对象就是创建后还可以改变状态的object。
例如String 和StringBuilder,String是immutable,每次对于String对象的修改都将产生一个新的String,而原来的对象保持不变,而StringBuilder是mutable,因为每次对它的对象的修改都作用与该对象本身。
immutable object比传统的mutable对象在多线程中更具有优势,它不仅能够保证对象的状态不被改变,而且还可以不使用锁机制被其他线程共享。
如何在Java中写出Immtable的类?
遵循以下几个原则:
(1)immutable对象的状态在创建之后就不能发生改变,任何对他的改变都应该产生一个新的对象。
(2)immutable类的所有属性都应该是final的。
(3)对象必须被正确的创建,比如对象引用在对象创建的过程中不能泄露
(4)对象应该是final的,以此来限制子类继承父类,避免子类改变父类的immutable属性。
(5)如果类中包含mutable类对象,那么返回给客户端的时候,返回该对象的一个拷贝,而不是该对象本身,类似第一条。
当然不完全遵守上面的原则也可以创建immutable类,比如String的hashcode就不是final的,但它能保证每次调用它的结果是一致的,无论多少次计算这个值,它都是一致的,因为这些值的都是通过计算final属性得来的。