原文链接:https://blog.csdn.net/xiangzh...

5、类加载器

程序在启动的时候,并不会一次性加载程序所要用的所有class文件,而是依据程序的须要,通过Java的类加载机制(ClassLoader)来动静加载某个class文件到内存当中的,从而只有class文件被载入到了内存之后,能力被其它class所援用。所以ClassLoader就是用来动静加载class文件到内存当中用的。

5.1、双亲委派原理
每个ClassLoader实例都有一个父类加载器的援用(不是继承关系,是一个蕴含的关系),虚拟机内置的类加载器(Bootstrap ClassLoader)自身没有父类加载器,然而能够用做其余ClassLoader实例的父类加载器。

当一个ClassLoader 实例须要加载某个类时,它会试图在亲自搜寻这个类之前先把这个工作委托给它的父类加载器,这个过程是由上而下顺次查看的,首先由顶层的类加载器Bootstrap CLassLoader进行加载,如果没有加载到,则把工作转交给Extension CLassLoader视图加载,如果也没有找到,则转交给AppCLassLoader进行加载,还是没有的话,则交给委托的发起者,由它到指定的文件系统或者网络等URL中进行加载类。还没有找到的话,则会抛出CLassNotFoundException异样。否则将这个类生成一个类的定义,并将它加载到内存中,最初返回这个类在内存中的Class实例对象。

5.2、 为什么应用双亲委托模型
JVM在判断两个class是否雷同时,不仅要判断两个类名是否雷同,还要判断是否是同一个类加载器加载的。

防止反复加载,父类曾经加载了,则子CLassLoader没有必要再次加载。
思考平安因素,假如自定义一个String类,除非扭转JDK中CLassLoader的搜寻类的默认算法,否则用户自定义的CLassLoader如法加载一个本人写的String类,因为String类在启动时就被疏导类加载器Bootstrap CLassLoader加载了。

对于Android的双亲委托机制,能够参考android classloader双亲委托模式

6、汇合

Java汇合类次要由两个接口派生出:Collection和Map,这两个接口是Java汇合的根接口。

Collection接口是汇合类的根接口,Java中没有提供这个接口的间接的实现类。然而却让其被继承产生了两个接口,就是 Set和List。Set中不能蕴含反复的元素。List是一个有序的汇合,能够蕴含反复的元素,提供了按索引拜访的形式。

Map是Java.util包中的另一个接口,它和Collection接口没有关系,是互相独立的,然而都属于汇合类的一部分。Map蕴含了key-value对。Map不能蕴含反复的key,然而能够蕴含雷同的value。

6.1、区别
List,Set都是继承自Collection接口,Map则不是;
List特点:元素有放入程序,元素可反复; Set特点:元素无放入程序,元素不可反复,反复元素会笼罩掉,(留神:元素尽管无放入程序,然而元素在set中的地位是有该元素的HashCode决定的,其地位其实是固定的,退出Set 的Object必须定义equals()办法;
LinkedList、ArrayList、HashSet是非线程平安的,Vector是线程平安的;
HashMap是非线程平安的,HashTable是线程平安的;

6.2、List和Vector比拟
Vector是多线程平安的,线程平安就是说多线程拜访同一代码,不会产生不确定的后果。而ArrayList不是,这个能够从源码中看出,Vector类中的办法很多有synchronized进行润饰,这样就导致了Vector在效率上无奈与ArrayList相比;
两个都是采纳的线性间断空间存储元素,然而当空间有余的时候,两个类的减少形式是不同。
Vector能够设置增长因子,而ArrayList不能够。
Vector是一种老的动静数组,是线程同步的,效率很低,个别不赞成应用。

6.3、HashSet如何保障不反复
HashSet底层通过HashMap来实现的,在往HashSet中增加元素是

`public boolean add(E e) {
return map.put(e, PRESENT)==null;
}

// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();
`

在HashMap中进行查找是否存在这个key,value始终是一样的,次要有以下几种状况:

  • 如果hash码值不雷同,阐明是一个新元素,存;
  • 如果hash码值雷同,且equles判断相等,阐明元素曾经存在,不存;
  • 如果hash码值雷同,且equles判断不相等,阐明元素不存在,存;
  • 如果有元素和传入对象的hash值相等,那么,持续进行equles()判断,如果依然相等,那么就认为传入元素曾经存在,不再增加,完结,否则依然增加;

6.4、HashSet与Treeset的实用场景

  • HashSet是基于Hash算法实现的,其性能通常都优于TreeSet。为疾速查找而设计的Set,咱们通常都应该应用HashSet,在咱们须要排序的性能时,咱们才应用TreeSet。
  • TreeSet 是二叉树(红黑树的树据构造)实现的,Treeset中的数据是主动排好序的,不容许放入null值
  • HashSet是哈希表实现的,HashSet中的数据是无序的,能够放入null,但只能放入一个null,两者中的值都不能反复,就如数据库中惟一束缚。
  • HashSet是基于Hash算法实现的,其性能通常都优于TreeSet。为疾速查找而设计的Set,咱们通常都应该应用HashSet,在咱们须要排序的性能时,咱们才应用TreeSet。

6.5、HashMap与TreeMap、HashTable的区别及实用场景
HashMap 非线程平安,基于哈希表(散列表)实现。应用HashMap要求增加的键类明确定义了hashCode()和equals()[能够重写hashCode()和equals()],为了优化HashMap空间的应用,您能够调优初始容量和负载因子。其中散列表的抵触解决次要分两种,一种是凋谢定址法,另一种是链表法。HashMap的实现中采纳的是链表法。
TreeMap:非线程平安基于红黑树实现,TreeMap没有调优选项,因为该树总处于均衡状态

点击下方链接收费获取Android进阶材料:

https://shimo.im/docs/tXXKHgd...