一、Java8新特性简介
1.1HashMap
JDK1.8以前
HashMap采用Hash表,如果HashMap不用Hash算法,那么效率将会极低。
因此采用Hash表(Hash算法)
Map Hash表默认大小是16,
当我要往里边添加一个对象的话,首先调用对象的HashCode方法,然后根据Hash算法对HashCode方法进行一个运算,生成一个数组的索引值(Hash表)。根据HashCode方法生成的Hash码值(假如计算出1),经过Hash算法运算(运算成数组的索引值)然后根据数组的索引值找到对应的位置,首先看这里有没有对象在,如果没有对象在,直接存储。
但是还会有一种情况:当我们创建对象调用HashCode方法,经过运算生成的Hash码值有可能还是1,此时发现对应位置已经存在对象,此时再通过equals比较两个对象的内容,如果内容一样,它的value就把原来value覆盖掉。但是若equals比较两个对象的内容不一样,那就形成链表,后加的放前面。这种情况我们称之为碰撞(这种情况我们要尽可能避免,如果链表元素过多,最后将形成效率低下)
所以我们应该尽可能避免,【HashCode和equals重写的时候,尽可能严谨,并且让HashCode方法和equals方法保持一致。对象的内容一样生成的HashCode值要一样,对象的内容一样,equals方法要返回true】
但是,即便HashCode方法和equals方法写的再严谨,碰撞的情况也还是避免不了。
当你创建对象,将其添加到HashMap中去的时候,HashMap采用的是Hash算法,把Hash码值经过运算,运算成数组的索引值。但是数组的索引值也就那么几个(0-15)
于是HashMap提供了加载因子,默认0.75【当元素到达现有Hash表的百分之75的时候进行扩容】一旦扩容就把链表里边的每一个元素重新进行运算,运算到扩容以后的新位置。
如此一来这样Hash碰撞的概率就降低了
但是即便你有扩容的机制,但是碰撞还是会不可避免。就意味着效率低。
于是在JDK1.8以后,就不是数组+链表了,而是数组+链表+红黑树。
如果碰撞的元素个数大于8(每个链表的长度大于8),并且在总元素大于64,这种情况下,链表就会转红黑树【优点:除了添加以外,其他操作都比链表快。】
1.2ConCurrentHashMap
JDK1.7之前并发级别默认16【concurrentLevel=16】。
在JDK1.8之后:改成CAS算法,无锁算法
1.3底层内存结构
二、Stream流
2.1什么是Stream流?
是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。
集合讲究的是数据,流讲究的是计算!
注意:
- Stream自己不会存储元素
- Stream不会改变源对象。相反,他们会返回一个持有结果的新Stream。
- Stream操作是延迟执行的,这就意味着他们会等到需要结果的时候才执行。
Stream的中间操作:
多个中间操作可以连接起来形成一个流水香,除非流水线上触发终止操作,否则中间操作不会执行任何的处理!而在终止操作时一次性全部处理,称之为"惰性求值"。