Tuesday, November 3, 2015
泛型与多重继承的关系 Java getGenericSuperclass()和getActualTypeArguments()基本用法:
遇到的问题,在处理的时候 我提取了多次的 BaseActivity. 结构是这样子的
DetailQRcodeActivity extends BaseQRcodeActivity
BaseQRcodeActivity extends CaptureActivity
CaptureActivity extends BaseActivity<SingleControl>
private void controlInit() { Class<?> clazz; clazz = mReferenceObj.getClass(); generateControl(clazz); if (mControl == null) { generateControl(clazz.getSuperclass()); } }
上面的处理方式:
1 mReferenceObj 是 DetailQRcodeActivity instance. 所以第一次调用 generateControl()
之后 mControl == null.
2 mReferenceObj,getSuperClass() 直接父类。也就是 BaseQRcodeActivity,这个时候调用
generateControl() 因为BaseQRcodeActivity extends CaptureActivity, 并没有泛型 的信息。也就是没有 SingleControl 类.
所以 此时 mControl == null ,这是为什么呢? 原来是因为泛型在继承的时候 之影响到 她的直接子类的信息。也就是他只会影响到CaptureActivity, 而对于她的孙子 BaseQRcodeActivity, 自然就 心有余而力不足啦!解决方案也就出来了, 第一种方法只解决当前的问题,或者以后每次写这种多继承的时候,需要添加。 第二种方案 从根本上解决问题。 我喜欢第二种。 这是在关联的时候有解决!
So how to reslove this problem?
1 First way:
you can follow this way
DetailQRcodeActivity extends BaseQRcodeActivity
BaseQRcodeActivity extends CaptureActivity< SingleControl >
CaptureActivity <? extends SingleControl > extends BaseActivity<SingleControl>
2 The second way: you can do this way
private void controlInit() { Class<?> clazz; clazz = mReferenceObj.getClass(); generateControl(clazz); if (mControl == null) { generateControl(clazz.getSuperclass()); } if (mControl == null){ generateControl(clazz.getSuperclass().getSuperclass()); } }
in a world I love the second way, because 一劳永逸!
=======================================================
核心代码:
http://blog.csdn.net/hikvision_java_gyh/article/details/10182309
private void generateControl(Class clazz) {
//1 getGenericSuperclass() //通过反射获取当前类表示的实体(类,接口,基本类型或void)的直接父类的Type,
//Type type = this.getClass().getGenericSuperclass();
//是得到这个类的得到泛型父类
Type type = clazz.getGenericSuperclass();
//3 (type instanceof ParameterizedType)),这行代码的意思是
// 如果没有实现ParameterizedType接口,即不支持泛型;
if (type instanceof ParameterizedType) {
ParameterizedType p = (ParameterizedType) type;
//2 getActualTypeArguments()返回参数数组。
//Type[] params = ((ParameterizedType) genType).getActualTypeArguments();这行代码的意思是,如果支持泛型,返回表示此类型实际类型参数的Type对象的数组,数组里放的都是对应类型的Class,因为可能有多个,所以是数组。
Type[] arrayClasses = p.getActualTypeArguments();
for (Type item : arrayClasses) {
if (item instanceof Class) {
Class<T> tClass = (Class<T>) item;
if (tClass.equals(BaseControl.class) || (tClass.getSuperclass() != null
&& tClass.getSuperclass().equals(BaseControl.class))) {
// the same deal with!
messageProxy = new MessageProxy(mHandler);
mControl = ControlFactory.getControlInstance(tClass,
messageProxy);
mModel = new ModelMap();
mControl.setModel(mModel);
return;
}
}
}
}
}
=======================================================
1.Class<? super T> getSuperclass():返回本类的父类
注意: 这里获取的 父类是直接父类奥。这里的继承只有一层的时候是可以的!
2.Type getGenericSuperclass():返回本类的父类,包含泛型参数信息
=========================================
附加 参考链接:
1 http://blog.csdn.net/hikvision_java_gyh/article/details/10182309
2 http://blog.csdn.net/u010167086/article/details/15336259
Monday, November 2, 2015
开发的心得感悟
在开发中,我们总是会遇到这样那样的问题。很多的时候我们似乎总是在跟Bug 打交道,有的时候我们会很烦的,因为各种问题,我也是蛋疼的问题!
我们也不喜欢自己的代码乱糟糟的样子,自己看以来费劲。自己都不喜欢的东西,你觉得别人会喜欢吗?我还是喜欢自己的东西。
1 短小的类
开发的时候,类要尽量的短小精悍。有的时候,我们似乎更远在一个类里面做更多的事情,其实不符合单一职责原则开发模式,因为在一个类里做了很多的事情, 当你添加一个心得功能的时候,你可能会纠结,我是要添加一个新的类呢?还是在原先类的基础上 添加 一个状态的判断呢? 我的建议看你的功能的大小。改动的比较多的时候建议使用新的类,这样的话,后期维护的时候,你不需要判断各种情况。 单一职责原则。当你在原有类的基础上修改的时候其实也违背了 开闭原则!
2 喜欢抽象类
我们会遇到各种奇葩的产品和老板。我们根本无法看到为阿里的产品需求,更多的时候竟然在我们 就要发布包的时候让我们去修改东西。这个时候,作为我们的衣食父母的话,我们可以反驳吗?这种情况是产品经经理的过时,但是当你没有产品经理的时候,我只能说你就苦逼了!抽象出 基本公共的部分方法。当你遇到新的功能的时候,你只需要添加新的功能就可以了,没有必要 公共的方法没有必要再重复的写,只要在父类里处理就好了!
3 起个好名字
这就不说了,起名字的时候,就像是给自己的儿子起名字就可以了!
4 方法
方法尽量的只负责一个功能,一个方法里面如果写的太多的话,就会画蛇添足,没有必要写那么多的没有必要的代码。一个方法尽量的只负责一个功能就好了,(这是不可能的,所以尽量吧。不可能所有的方法只负责一个功能!)
5 先思考在code
我们都会遇到这种情况,有的新的要求的时候,我们想都不想的就开始一顿乱写,写完之后,又要花费成倍的时间来填自己的挖出的坑。这是一个蛋疼的问题,因为我们测试花的时候是编码的好几倍。这是,如果你是Android你会发现,这阵的很浪费时间。
6 承认自己的技术坑
每个人都有自己不知道的知识点,以前的我总是自大的以为自己的技术是最牛逼的,自从来到这家公司之后,我就发现其实自己真的是坑的,loser. 我以前从来没有发现自己的缺点 是自己的指点
AOP 面向切面开发?
一,什么是AOP
AOP(Aspect Orient Programming),也就是面向切面编程。可以这样理解,面向对象编程(OOP)是从静态角度考虑程序结构,面向切面编程(AOP)是从动态角度考虑程序运行过程。
二、AOP 的作用。
常常通过 AOP 来处理一些具有横切性质的系统性服务,如事物管理、安全检查、缓存、对象池管理等,AOP 已经成为一种非常常用的解决方案。
三、AOP 的实现原理

参考链接:
AOP 还是比较麻烦的问题:
http://www.iteye.com/topic/1116696
感悟!
参考链接:
1 http://www.zhihu.com/question/24863332
2 http://www.iteye.com/topic/1116696
华为荣耀6P 如何刷机?
华为荣耀手机刷机的时候是比较恶心的问题,因为之前我找了很多的文章都说只要下载几个工具就好了,其实并是不那么简单的,以为很简单的事情往往会发花费大量的时间呢!真的是很恶心的,因为 华为荣耀有一个 锁,所以 如果不经解锁的话,你是无法刷机的奥,
解锁的方式如下:
1. 为什么要解锁?
华为手机一般具有系统锁,不能直接刷第三方ROM,解锁是为了能刷入第三方recovery,即刷入第三方ROM包。
2. 怎样申请解锁码?
1)首先申请解锁码,打开申请地址: http://www.emui.com/plugin.php?id=unlock,勾选“我已阅读以上条款并接受所有内容”,选择下一步,选择机型为荣耀6Plus相应版本机型。
2)查询手机S/N号查询:在手机的拨号界面输入*#*#2846579#*#*,进入ProjectMenu - 单板基本信息查询 - 其他查询,即可看到S/N号。
3)查询手机IMEI/MEID号:在手机的拨号界面输入*#06#即可显示出IMEI号(双卡手机,输入主IMEI/MEID号)。
4)查询手机识别码:在手机的拨号界面输入*#*#1357946#*#*,可以看到8位数字识别码。 5)最后填写网页验证码,点击确认即可,稍等片刻后即可看到下方显示红色字,即为你手持设备的解锁码。当然你也可以发邮件申请,不过比较麻烦。

无标.png (156.08 KB, 下载次数: 108)
下载附件 保存到相册
2015-2-5 16:01 上传
3.如何进行解锁?
首先,如果解锁过程中如果遇到手机没有自动重启,请直接忽略进行下一步即可。
本帖隐藏的内容 1) 安装驱动及adb工具,这里推荐大家使用改工具 :bbs.anzhi.com/thread-9007695-1-1.html ,非常适合新手,另外切勿忘记开启adb调试,我们下面都会用到,方法:设置-关于手机,然后连续点击版本号,5次后即可进入开发者模式,退回到上级,你会看到开发者选项,进入后开启USB调试即可(还不会的可以百度了解下具体开启过程)。
2)点击左下角WIN图标,在搜索文件处输入 cmd ,然后回车,即可弹出cmd命令窗口,输入adb devices,回车,如果看到类似下面第一张图输出结果,说明adb驱动及工具已成功搞定!如果出现类似第二张图的输出结果,请在进程管理器里结束掉其他任何手机连接类的进程。。

3) 然后输入 adb reboot-bootloader,手机将重启并进入一个白色背景的界面,这就是fastboot模式。

4)输入fastboot devices,即可类似如下的输出。

再输入 fastboot oem unlock ****************,*号为16位解锁密码,例如:fastboot oem unlock 1234567812345678,回车确认,将会看到如下输出,手机将发生重启,重新进入fastboot模式,不出意外,已经解锁成功。

5)我们可以查看下是否已经成功解锁,输入 fastboot oem get-bootinfo ,回车,将会看到如下输出结果,状态为unlocked 即为解锁成功。

6)最后输入 fastboot reboot,手机即可重启到系统。
4. 如何重新上锁?
解锁过程基本与解锁相似,再次不作赘述,注意解锁命令为 fastboot oem relock **************** ,用 fastboot oem get-bootinfo 命令查看时状态为relocked。
=================================================
我遇到的问题:用于申请解锁码的华为云账号未在本手机上登录超过14天!
华为 卧槽!
一个恶心的消息:你必须要 开一华为云服务。我用了半年的手机,并没有开启 云服务。感觉 华为真他妈的垃圾!
参考链接:
1 http://tieba.baidu.com/p/3678718686
解锁的方式如下:
1. 为什么要解锁?
华为手机一般具有系统锁,不能直接刷第三方ROM,解锁是为了能刷入第三方recovery,即刷入第三方ROM包。
2. 怎样申请解锁码?
1)首先申请解锁码,打开申请地址: http://www.emui.com/plugin.php?id=unlock,勾选“我已阅读以上条款并接受所有内容”,选择下一步,选择机型为荣耀6Plus相应版本机型。
2)查询手机S/N号查询:在手机的拨号界面输入*#*#2846579#*#*,进入ProjectMenu - 单板基本信息查询 - 其他查询,即可看到S/N号。
3)查询手机IMEI/MEID号:在手机的拨号界面输入*#06#即可显示出IMEI号(双卡手机,输入主IMEI/MEID号)。
4)查询手机识别码:在手机的拨号界面输入*#*#1357946#*#*,可以看到8位数字识别码。 5)最后填写网页验证码,点击确认即可,稍等片刻后即可看到下方显示红色字,即为你手持设备的解锁码。当然你也可以发邮件申请,不过比较麻烦。
无标.png (156.08 KB, 下载次数: 108)
下载附件 保存到相册
2015-2-5 16:01 上传
3.如何进行解锁?
首先,如果解锁过程中如果遇到手机没有自动重启,请直接忽略进行下一步即可。
本帖隐藏的内容 1) 安装驱动及adb工具,这里推荐大家使用改工具 :bbs.anzhi.com/thread-9007695-1-1.html ,非常适合新手,另外切勿忘记开启adb调试,我们下面都会用到,方法:设置-关于手机,然后连续点击版本号,5次后即可进入开发者模式,退回到上级,你会看到开发者选项,进入后开启USB调试即可(还不会的可以百度了解下具体开启过程)。
2)点击左下角WIN图标,在搜索文件处输入 cmd ,然后回车,即可弹出cmd命令窗口,输入adb devices,回车,如果看到类似下面第一张图输出结果,说明adb驱动及工具已成功搞定!如果出现类似第二张图的输出结果,请在进程管理器里结束掉其他任何手机连接类的进程。。
3) 然后输入 adb reboot-bootloader,手机将重启并进入一个白色背景的界面,这就是fastboot模式。
4)输入fastboot devices,即可类似如下的输出。
再输入 fastboot oem unlock ****************,*号为16位解锁密码,例如:fastboot oem unlock 1234567812345678,回车确认,将会看到如下输出,手机将发生重启,重新进入fastboot模式,不出意外,已经解锁成功。
5)我们可以查看下是否已经成功解锁,输入 fastboot oem get-bootinfo ,回车,将会看到如下输出结果,状态为unlocked 即为解锁成功。
6)最后输入 fastboot reboot,手机即可重启到系统。
4. 如何重新上锁?
解锁过程基本与解锁相似,再次不作赘述,注意解锁命令为 fastboot oem relock **************** ,用 fastboot oem get-bootinfo 命令查看时状态为relocked。
=================================================
我遇到的问题:用于申请解锁码的华为云账号未在本手机上登录超过14天!
华为 卧槽!
一个恶心的消息:你必须要 开一华为云服务。我用了半年的手机,并没有开启 云服务。感觉 华为真他妈的垃圾!
参考链接:
1 http://tieba.baidu.com/p/3678718686
Sunday, November 1, 2015
Java 集合之旅
世间上本来没有集合,(只有数组参考C语言)但有人想要,所以有了集合
有人想有可以自动扩展的数组,所以有了List
有的人想有没有重复的数组,所以有了set
有人想有自动排序的组数,所以有了TreeSet,TreeList,Tree**
而几乎有有的集合都是基于数组来实现的.
因为集合是对数组做的封装,所以,数组永远比任何一个集合要快。
但任何一个集合,比数组提供的功能要多
一:数组声明了它容纳的元素的类型,而集合不声明。这是由于集合以object形式来存储它们的元素。
二:一个数组实例具有固定的大小,不能伸缩。集合则可根据需要动态改变大小。
三:数组是一种可读/可写数据结构---没有办法创建一个只读数组。然而可以使用集合提供的ReadOnly方法,以只读方式来使用集合。该方法将返回一个集合的只读版本。
==============================================================
MAP : INFO
/**
* An object that maps keys to values. A map cannot contain duplicate keys;
* each key can map to at most one value.
*
* <p>This interface takes the place of the <tt>Dictionary</tt> class, which
* was a totally abstract class rather than an interface.
*
* <p>The <tt>Map</tt> interface provides three <i>collection views</i>, which
* allow a map's contents to be viewed as a set of keys, collection of values,
* or set of key-value mappings. The <i>order</i> of a map is defined as
* the order in which the iterators on the map's collection views return their
* elements. Some map implementations, like the <tt>TreeMap</tt> class, make
* specific guarantees as to their order; others, like the <tt>HashMap</tt>
* class, do not.
*
* <p>Note: great care must be exercised if mutable objects are used as map
* keys. The behavior of a map is not specified if the value of an object is
* changed in a manner that affects <tt>equals</tt> comparisons while the
* object is a key in the map. A special case of this prohibition is that it
* is not permissible for a map to contain itself as a key. While it is
* permissible for a map to contain itself as a value, extreme caution is
* advised: the <tt>equals</tt> and <tt>hashCode</tt> methods are no longer
* well defined on such a map.
*
* <p>All general-purpose map implementation classes should provide two
* "standard" constructors: a void (no arguments) constructor which creates an
* empty map, and a constructor with a single argument of type <tt>Map</tt>,
* which creates a new map with the same key-value mappings as its argument.
* In effect, the latter constructor allows the user to copy any map,
* producing an equivalent map of the desired class. There is no way to
* enforce this recommendation (as interfaces cannot contain constructors) but
* all of the general-purpose map implementations in the JDK comply.
*
* <p>The "destructive" methods contained in this interface, that is, the
* methods that modify the map on which they operate, are specified to throw
* <tt>UnsupportedOperationException</tt> if this map does not support the
* operation. If this is the case, these methods may, but are not required
* to, throw an <tt>UnsupportedOperationException</tt> if the invocation would
* have no effect on the map. For example, invoking the {@link #putAll(Map)}
* method on an unmodifiable map may, but is not required to, throw the
* exception if the map whose mappings are to be "superimposed" is empty.
*
* <p>Some map implementations have restrictions on the keys and values they
* may contain. For example, some implementations prohibit null keys and
* values, and some have restrictions on the types of their keys. Attempting
* to insert an ineligible key or value throws an unchecked exception,
* typically <tt>NullPointerException</tt> or <tt>ClassCastException</tt>.
* Attempting to query the presence of an ineligible key or value may throw an
* exception, or it may simply return false; some implementations will exhibit
* the former behavior and some will exhibit the latter. More generally,
* attempting an operation on an ineligible key or value whose completion
* would not result in the insertion of an ineligible element into the map may
* throw an exception or it may succeed, at the option of the implementation.
* Such exceptions are marked as "optional" in the specification for this
* interface.
*
* <p>Many methods in Collections Framework interfaces are defined
* in terms of the {@link Object#equals(Object) equals} method. For
* example, the specification for the {@link #containsKey(Object)
* containsKey(Object key)} method says: "returns <tt>true</tt> if and
* only if this map contains a mapping for a key <tt>k</tt> such that
* <tt>(key==null ? k==null : key.equals(k))</tt>." This specification should
* <i>not</i> be construed to imply that invoking <tt>Map.containsKey</tt>
* with a non-null argument <tt>key</tt> will cause <tt>key.equals(k)</tt> to
* be invoked for any key <tt>k</tt>. Implementations are free to
* implement optimizations whereby the <tt>equals</tt> invocation is avoided,
* for example, by first comparing the hash codes of the two keys. (The
* {@link Object#hashCode()} specification guarantees that two objects with
* unequal hash codes cannot be equal.) More generally, implementations of
* the various Collections Framework interfaces are free to take advantage of
* the specified behavior of underlying {@link Object} methods wherever the
* implementor deems it appropriate.
*
* <p>Some map operations which perform recursive traversal of the map may fail
* with an exception for self-referential instances where the map directly or
* indirectly contains itself. This includes the {@code clone()},
* {@code equals()}, {@code hashCode()} and {@code toString()} methods.
* Implementations may optionally handle the self-referential scenario, however
* most current implementations do not do so.
*
* <p>This interface is a member of the
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
* Java Collections Framework</a>.
*
* @param <K> the type of keys maintained by this map
* @param <V> the type of mapped values
*
* @author Josh Bloch
* @see HashMap
* @see TreeMap
* @see Hashtable
* @see SortedMap
* @see Collection
* @see Set
* @since 1.2
*/
==============================================================
HashMap的实现原理 (讲的不是很清晰)
==============================================================
look the picture:
pic 1
pic 2
HashMap put source:
1)put
疑问:如果两个key通过hash%Entry[].length得到的index相同,会不会有覆盖的危险?
这里HashMap里面用到链式数据结构的一个概念。上面我们提到过Entry类里面有一个next属性,作用是指向下一个Entry。打个比方, 第一个键值对A进来,通过计算其key的hash得到的index=0,记做:Entry[0] = A。一会后又进来一个键值对B,通过计算其index也等于0,现在怎么办?HashMap会这样做:B.next = A,Entry[0] = B,如果又进来C,index也等于0,那么C.next = B,Entry[0] = C;这样我们发现index=0的地方其实存取了A,B,C三个键值对,他们通过next这个属性链接在一起。所以疑问不用担心。也就是说数组中存储的是最后插入的元素。到这里为止,HashMap的大致实现,我们应该已经清楚了。
/**
* Maps the specified key to the specified value.
*
* @param key
* the key.
* @param value
* the value.
* @return the value of any previous mapping with the specified key or
* {@code null} if there was no such mapping.
*/
@Override public V put(K key, V value) {
if (key == null) {
return putValueForNullKey(value);
}
int hash = Collections.secondaryHash(key);
HashMapEntry<K, V>[] tab = table;
int index = hash & (tab.length - 1);
//1 如果key在链表中已存在,则替换为新value
// 看了好一会儿,终于看明白了。这一过程是,当你新添加的元素 不仅 HashCode 一样。而且Key 也是一样的时候,就是 有重复的数据的时候 需要讲老的数据 替换,保证唯一性!
for (HashMapEntry<K, V> e = tab[index]; e != null; e = e.next) {
if (e.hash == hash && key.equals(e.key)) {
preModify(e);
V oldValue = e.value;
e.value = value;
return oldValue;
}
}
// No entry for (non-null) key is present; create one
modCount++;
if (size++ > threshold) {
//3 当你的 table[] 内存太小的时候就会调用该方法 分配更大的内存空间!
tab = doubleCapacity();
index = hash & (tab.length - 1);
}
//2 添加实体(其实是 zai'xiaindex替换下来的老的实体)
// 这里才是真正的加入table[] 数据。 当你的HashCode 一样的时候,就调用这个方法。将老的数据的位置用新的数据替换, 老的数据后移一位!
addNewEntry(key, value, hash, index);
return null;
}
/**
* Computes a hash code and applies a supplemental hash function to defend
* against poor quality hash functions. This is critical because HashMap
* uses power-of-two length hash tables, that otherwise encounter collisions
* for hash codes that do not differ in lower or upper bits.
* Routine taken from java.util.concurrent.ConcurrentHashMap.hash(int).
* @hide
*/
public static int secondaryHash(Object key) {
return secondaryHash(key.hashCode());
}
2 let me see:
/**
* Creates a new entry for the given key, value, hash, and index and
* inserts it into the hash table. This method is called by put
* (and indirectly, putAll), and overridden by LinkedHashMap. The hash
* must incorporate the secondary hash function.
*/
void addNewEntry(K key, V value, int hash, int index) {
table[index] = new HashMapEntry<K, V>(key, value, hash, table[index]);
}
3 当你的 table[] 内存太小的时候就会调用该方法 分配更大的内存空间!
/**
* Doubles the capacity of the hash table. Existing entries are placed in
* the correct bucket on the enlarged table. If the current capacity is,
* MAXIMUM_CAPACITY, this method is a no-op. Returns the table, which
* will be new unless we were already at MAXIMUM_CAPACITY.
*/
private HashMapEntry<K, V>[] doubleCapacity() {
HashMapEntry<K, V>[] oldTable = table;
int oldCapacity = oldTable.length;
if (oldCapacity == MAXIMUM_CAPACITY) {
return oldTable;
}
int newCapacity = oldCapacity * 2;
HashMapEntry<K, V>[] newTable = makeTable(newCapacity);
if (size == 0) {
return newTable;
}
for (int j = 0; j < oldCapacity; j++) {
/*
* Rehash the bucket using the minimum number of field writes.
* This is the most subtle and delicate code in the class.
*/
HashMapEntry<K, V> e = oldTable[j];
if (e == null) {
continue;
}
int highBit = e.hash & oldCapacity;
HashMapEntry<K, V> broken = null;
newTable[j | highBit] = e;
for (HashMapEntry<K, V> n = e.next; n != null; e = n, n = n.next) {
int nextHighBit = n.hash & oldCapacity;
if (nextHighBit != highBit) {
if (broken == null)
newTable[j | nextHighBit] = n;
else
broken.next = n;
broken = e;
highBit = nextHighBit;
}
}
if (broken != null)
broken.next = null;
}
return newTable;
}
哈希表有多种不同的实现方法
==============================================================
2. Get
获取的思想比较简单。不需要判断有没有重复的元素:
原理:
跟HashCode 获取元素在HashTable中的位置 index. 然后判断Key是不是相同,如果相同取出。 否则循环遍历链表。
/**
* Returns the value of the mapping with the specified key.
*
* @param key
* the key.
* @return the value of the mapping with the specified key, or {@code null}
* if no mapping for the specified key is found.
*/
public V get(Object key) {
if (key == null) {
HashMapEntry<K, V> e = entryForNullKey;
return e == null ? null : e.value;
}
int hash = Collections.secondaryHash(key);
HashMapEntry<K, V>[] tab = table;
for (HashMapEntry<K, V> e = tab[hash & (tab.length - 1)];
e != null; e = e.next) {
K eKey = e.key;
// Key code in this line
if (eKey == key || (e.hash == hash && key.equals(eKey))) {
return e.value;
}
}
return null;
}
==============================================================
==============================================================
See the UML
总结:
HashMap是基于”拉链法“实现的散列表,一般用于单线程,键值都可以为空,支持Iterator(迭代器)遍历
Hashtable是基于”拉链法“实现的散列表,是线程安全的,可以用于多线程程序中。支持Iterator(迭代器)遍历和Enumeration(枚举器)两种遍历方式。
WeakHashMap也是基于”拉链法“实现的散列表,同时是弱键
TreeMap 是有序的散列表,通过红黑树来实现的,键值都不能为空。
==============================================================
5 TreeMap 的源码分析 http://liujiacai.net/blog/2015/09/04/java-treemap/
写的非常的不错,因为是我的学长 哈哈
参考链接:
1 http://blog.csdn.net/speedme/article/details/22398395
2 http://blog.csdn.net/shimiso/article/details/10181801
3 http://blog.csdn.net/vking_wang/article/details/14166593
4 http://blog.csdn.net/qq924862077/article/details/48039643
5 http://liujiacai.net/blog/2015/09/04/java-treemap/
Subscribe to:
Posts (Atom)







