当前位置: 首页 > news >正文

视频网站的建设目标服装定制价格

视频网站的建设目标,服装定制价格,手机版网页制作软件,网站建设推销员话术原创/朱季谦 一、案例场景 遇到过这样的场景#xff0c;在定义一个static修饰的Map时#xff0c;使用了大量的put()方法赋值#xff0c;就类似这样—— public static final MapString,String dayMap new HashMap(); static {dayMap.put(Monday在定义一个static修饰的Map时使用了大量的put()方法赋值就类似这样—— public static final MapString,String dayMap new HashMap(); static {dayMap.put(Monday,今天上英语课);dayMap.put(Tuesday,今天上语文课);dayMap.put(Wednesday,今天上数学课);dayMap.put(Thursday,今天上音乐课);dayMap.put(Sunday,今天上编程课);...... }当时我就在想是否可以进一步优化下使得代码看起来更为优雅些然后就发现了Google Guava里的有一个类ImmutableMap通过这个类可以实现类似建造者模式的链式编程优化后的效果如下 public static final MapString,String dayMap ImmutableMap.String, Stringbuilder().put(Monday,今天上英语课).put(Tuesday,今天上语文课).put(Wednesday,今天上数学课).put(Thursday,今天上音乐课).put(Sunday,今天上编程课).build();二、ImmutableMap源码分析 那么这个ImmutableMap究竟是如何实现这样的功能呢 在Google Guava官方教程中Immutable前缀的集合被定义为不可变集合包括ImmutableSet、 ImmutableMap等何为不可变集合就是指在集合创建后集合里所有的状态在生命周期内都不可再修改了只能读。 那么什么是可再修改的呢像Jdk中的map、list等创建后还可以再通过put()或者add()反复新增或者修改这种就是可再修改的集合。既然是不可再修改集合是不是就一定不能再修改了呢也不是其实通过反射还是可以被修改的但这已经不是不可变集合之所以存在的初衷了。 总结一句话是不可变集合是线程安全的且可当成常量使用的。 接下来就进入到ImmutableMap内部可以看到其实现了Map接口跟HashMap有点类似地方在于Map接口都算是他们的基类都可以实现父类引用指向子类对象即向上转型。 public abstract class ImmutableMapK, V implements MapK, V, Serializable {}这是一个抽象类若要实现这样调用 ImmutableMap.String, Stringbuilder()表面上就可以猜测到String, Stringbuilder()一定是被static定义的静态方法进到源码里发现确实如此—— /*** Returns a new builder. The generated builder is equivalent to the builder* created by the {link Builder} constructor.*/ public static K, V BuilderK, V builder() {return new BuilderK, V(); }这个方法的定义对于一些初级程序员而言可能会觉得很奇怪其实这个方法格式的本质是这样的 —— public T T method(T t)这是一种泛型的约定规范第一个定义一种泛型表示当前方法有一个范型变量类型用T表示第二个T是表示method的返回类型为T。 回过头来看这个builder()方法就很好理解了K, V是定义一种泛型表示当前方法的泛型变量BuilderK, V表示返回一个泛型变量为K, V的对象。 前面定义 ImmutableMap.String, Stringbuilder()在这个builder()方法里就会返回一个new BuilderString, String()的对象这个对象通过构造器初始化了一个大小为ImmutableCollection.Builder.DEFAULT_INITIAL_CAPACITY的数组entries而这个DEFAULT_INITIAL_CAPACITY的默认值是4。 public static class BuilderK, V {Comparator? super V valueComparator;ImmutableMapEntryK, V[] entries;int size;boolean entriesUsed;public Builder() {this(ImmutableCollection.Builder.DEFAULT_INITIAL_CAPACITY);}Builder(int initialCapacity) {this.entries new ImmutableMapEntry[initialCapacity];this.size 0;this.entriesUsed false;}...... }那么问题来了这个 ImmutableMapEntryK, V[] 是什么类型的数组呢 这个ImmutableMapEntryK, V类 是继承一个ImmutableEntryK, V类 —— class ImmutableMapEntryK, V extends ImmutableEntryK, V {static K, V ImmutableMapEntryK, V[] createEntryArray(int size) {return new ImmutableMapEntry[size];}ImmutableMapEntry(K key, V value) {super(key, value);checkEntryNotNull(key, value);} }注意一点 checkEntryNotNull(key, value)做了一个校验这就意味着存入的key和value值都不能为空。 static void checkEntryNotNull(Object key, Object value) {if (key null) {throw new NullPointerException(null key in entry: null value);} else if (value null) {throw new NullPointerException(null value in entry: key null);} }在父类ImmutableEntryK, V类里定义了key和value两个泛型变量可见当外部调用builder().put(keyvalue)来存储key-value数据时其实是将key-value数据存储到ImmutableEntry对象的key与value里。 class ImmutableEntryK, V extends AbstractMapEntryK, V implements Serializable {final K key;final V value;...... }提到ImmutableEntryK, V数组来存储key-value数据就不得不提一下HashMap。 在JDK1.8当中HashMap是由数组链表红黑树组成它内部的数组是由NodeK,V[]定义而这个 NodeK,V 实现的是Map.EntryK,V—— ImmutableMapEntryK, V顶部同样是实现了EntryK,V—— 可见ImmutableMap与HashMap一样其存储key-value的对象所属的类都直接或者间接地实现了EntryK,V接口。 分析到这里再看回BuilderK, V类源码就很容易明白 这个ImmutableMapEntryK, V[] entries与HashMap的数组类似都是用来存储key-value的数据。 接下来就是分析put的逻辑原理了。 前面分析到的Builder类其实是属于抽象类 ImmutableMapK, V中的内部静态类这就意味着执行ImmutableMap.String, Stringbuilder().put(Monday,今天上英语课)的本质其实是相当于执行了ImmutableMap.new BuilderK, V().put(Monday,今天上英语课)。 put方法的源码如下 public BuilderK, V put(K key, V value) {ensureCapacity(size 1); ImmutableMapEntryK, V entry entryOf(key, value);// dont inline this: we want to fail atomically if key or value is nullentries[size] entry;return this; }一、先看第一行代码调用的方法其作用是判断当新增一个key-value对象存到数组时是否会有溢出的可能若出现溢出的情况就先对数组进行扩容。 private void ensureCapacity(int minCapacity) {if (minCapacity entries.length) {entries Arrays.copyOf(entries, ImmutableCollection.Builder.expandedCapacity(entries.length, minCapacity));entriesUsed false;} }二、第二行ImmutableMapEntryK, V entry entryOf(key, value)就是创建一个新的ImmutableMapEntry对象通过构造器初始化赋值给对象的key与value—— static K, V ImmutableMapEntryK, V entryOf(K key, V value) {return new ImmutableMapEntryK, V(key, value);}三、第三行代码 entries[size] entry是将新增的ImmutableMapEntry对象存储到数组空闲的位置上这样通过put(keyvalue)缓存进来的key-value值就通过对象的形式存入到了数组当中。 四、最后一行是返回一个thisImmutableMap能实现链式编程的原因就是在这个this上。 当理解了这个this就会理解ImmutableMap设计的精妙之处。 当我们使用链式编程ImmutableMap.String, Stringbuilder().put(key1,value1).put(key2,value2) .put(key2,value3)来赋值时其内部就是反复调用了内部静态类Builder当中的put()方法那么问题来了为什么能反复调用呢 答案就是这个返回的this其返回的还是Builder对象本身啊Builderd对象当然可以继续调用其put方法了。在这个反复调用的过程中 只有entries[size] 是一直在新增变化的。 这其实是建造者设计模式的一种体现只不过平常遇到的建造者设计模式大多都是将对象的各个属性灵活进行拼装组成一个定制化的对象而这里则是灵活去定制化一个数组存储情况。 最后就是就是执行.build()方法了—— ImmutableMap.String, Stringbuilder().put(Monday,今天上英语课).......build();这个build()源码里写的很复杂这里直接简单优化了下大概意思就是将entries数组包装成一个实现Map接口的子对象进行返回。 public ImmutableMapK, V build() {switch (size) {case 0:return of();case 1:return new SingletonImmutableBiMapK, V(k1, v1);default:return new RegularImmutableMapK, V(entries, table, mask);} }当数组长度超过1时其可以返回SingletonImmutableBiMap或者RegularImmutableMap两者都是间接实现了Map接口对比一下各自的类定义—— final class SingletonImmutableBiMapK, V extends ImmutableBiMapK, V {final transient K singleKey;final transient V singleValue;...... }final class RegularImmutableMapK, V extends ImmutableMapK, V {// entries in insertion orderprivate final transient EntryK, V[] entries;// array of linked lists of entriesprivate final transient ImmutableMapEntryK, V[] table;// and with an int to get a table indexprivate final transient int mask;...... }发现都有一个共同特点类与类中的属性都是以final修饰符来定义的这就意味着一旦调用build()方法创建初始化后就不可以再改变了。 这就是ImmutableMap集合不可变的真正原因所在。 最后还有一个问题是当通过ImmutableMap创建完成一个Map对象后再试图通过put来插入数据时会发生什么情况呢 这时再通过put方法调用时例如以上边定义的dayMap为例在某个方法里再试图通过dayMap..put(Monday,今天上英语课) 来修改或者新增map数据时这里调用的put就已经不是内部类BuilderK, V()里的put方法了而是ImmutableMap本身的put方法这个方法的源码如下—— /*** Guaranteed to throw an exception and leave the map unmodified.** throws UnsupportedOperationException always* deprecated Unsupported operation.*/ CanIgnoreReturnValue Deprecated Override public final V put(K k, V v) {throw new UnsupportedOperationException(); }其注释表示map unmodified即无法再被修改若仍调用put执行只会喜提一个异常 UnsupportedOperationException。
http://www.zqtcl.cn/news/229477/

相关文章:

  • 为何只有建设银行网站打不开阳江网络问政
  • 浦东做营销网站河北黄骅市网站建设
  • 青岛哪里有做网站公司的东莞东坑网站设计
  • 建站公司是什么郴州网站建设哪家做的好
  • 鞍山市住房和城乡建设网站网站几个数据库
  • 网站的内容建设安徽做网站
  • 有建网站的软件深圳专业做网站专业公司
  • 成都建设网站的公司汕尾海丰建设规划局网站
  • 南京cms建站企业网站的优化
  • 织梦网络设计工作室网站模板wordpress %postname%
  • 网站建设默认字体2020广东黄页
  • 金融电子商务网站建设深圳有什么公司名称
  • 网站设计 术语wordpress 图片弹出
  • 哪些域名不能够做淘宝客网站查建设公司年度保证金网站
  • 自己怎样用手机建网站网站优化 北京
  • 深圳小语种网站建设深圳做网站哪个平台好
  • 给个高质量的网站做网站优化有前景吗
  • 外贸网站 源怎么利用互联网平台赚钱
  • 营销型网站建设平台wordpress 添加 常规
  • php主做哪种类型网站高端公司小程序建设
  • 网站域名301是什么意思在一呼百应上做网站行吗
  • 怎么做百度口碑网站郑州网站设计专家
  • 珠海网络公司网站建设邯郸铸邯网络信息科技有限公
  • 室内设计者联盟官网哈尔滨百度搜索排名优化
  • 网站公司打电话来说做网站天下信息网
  • 汕头制作企业网站百度舆情监测平台
  • 怎样跟网站做优化呢火狐搜索引擎
  • 如何做网站的维护和推广水利网站建设管理汇报
  • 申请网站就是做网站吗怎样凡科建设网站
  • 怎样做吓人网站网页制作成品图