-
使用Lambda表达式遍历集合:程序调用Iterable的forEach(Consumer action)遍历集合元素时,程序一次将集合元素传给Consumer的accept(T t)方法。
-
使用Iterator遍历集合元素:必须依附于Collection对象,void forEachRemaining(Consumer action)可以使用Lambda表达式来遍历集合元素。
-
使用foreach循环遍历集合元素
-
使用Predicate操作集合:Java 8新增remove(Predicate filter)方法,批量删除符合filter条件的所有元素,Predicate也是函数式接口,可使用Lambda表达式作为参数。
-
使用Stream操作集合
Set:
-
HashSet:不能保证元素的排列顺序,非同步,元素值可以是null,判断两个对象是否相等:equals和hashCode必须都相等
-
LinkedHashSet:根据元素的hashCode来决定元素的存储位置,同时使用链表维护元素的次序,按元素的添加顺序来访问集合里的元素。
-
TreeSet:使用红黑树实现
-
EnumSet:
- 为枚举类设计,有序性能最好
- 内部以位向量形式存储
- 不允许加入null元素
List:Java8新增listIterator接口,增加向前前迭代功能。
- ArrayList与vector:
- Vector是线程安全的,而ArrayList是线程序不安全,效率高;
- ArrayList与Vector都有一个初始的容量大小,当存储进它们里面的元素的个数超过了容量时,就需要增加ArrayList与Vector的存储空间,每次要增加存储空间时,不是只增加一个存储单元,而是增加多个存储单元,每次增加的存储单元的个数在内存空间利用与程序效率之间要取得一定的平衡。Vector默认增长为原来两倍,而ArrayList的增长策略在文档中没有明确规定(从源代码看到的是增长为原来的1.5倍)。ArrayList与Vector都可以设置初始的空间大小,Vector还可以设置增长的空间大小,而ArrayList没有提供设置增长空间的方法。
- Stack:模拟栈,线程安全
固定长度的List:Arrays.asList(Object…a),Arrays内部类的实例
Queue:模拟队列
-
PriorityQueue:队列实现类
-
Deque:双端队列,即可当队列,又可当栈使用
-
ArrayDeque:作为栈使用,内部和ArrayList都采用一个动态的、可重新分配的object[] 数组来存储集合元素。
-
LinkedList:即可当双端队列,又可当栈,内部以链表的形式来保存集合元素。
Map
- HashMap和Hashtable
a) 继承不同。 public class Hashtable extends Dictionary implements Map public class HashMap extends AbstractMap implements Map
b) Hashtable线程安全而HashMap不是线程安全的。
c) Hashtable 中, key 和 value 都不允许出现 null 值。 在 HashMap 中, null 可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为 null 。
d) 两个遍历方式的内部实现上不同。Hashtable、HashMap都使用了Iterator。Hashtable还使用了Enumeration的方式 。
e) 哈希值的使用不同,HashTable直接使用对象的hashCode。而HashMap重新计算hash值。
f) Hashtable和HashMap它们两个内部实现方式的数组的初始大小和扩容的方式。HashTable中hash数组默认大小是11,增加的方式是old*2+1。HashMap中hash数组的默认大小是16,而且一定是2的指数。 HashSet内部使用Map保存数据,即将HashSet的数据作为Map的key值保存,这也是HashSet中元素不能重复的原因。而Map中保存key值的,会去判断当前Map中是否含有该Key对象,内部是先通过key的hashCode,确定有相同的hashCode之后,再通过equals方法判断是否相同。
-
LinkedHashMap:使用双向链表维护key-value对的次序
-
WeakHashMap与HashMap区别:
HashMap的key保留了对实际对象的强引用,这意味着只要该对象不被销毁,该HashMap的所有key所引用的对象就不会被垃圾回收,HashMap也不会自动删除这些key所对应的key-value对,但WeakHashMap的key只保留了对实际对象的弱引用,这意味着如果WeakHashMap对象的key所引用的对象没有被其他强引用变量所引用,则这些key所引用的对象可能被垃圾回收,WeakHashMap会自动删除这些key所引用的key-value对。
-
IdentityHashMap:当且仅当两个key严格相等(key1 == key2)时,才认为两个key相等,而HashMap只要equals方法和hashcode相等即可。
-
EnumMap:一个与枚举类一起使用的Map实现,EnumMap中的所有key都必须是单个枚举类的枚举值
- EnumMap在内部以数组形式保存
- 根据key的自然顺序来维护key-value对的顺序
- 不允许使用null作为key
-
TreeMap:红黑树结构,每个key-value对即为红黑树一个节点。
-
Properties:读写属性文件
并发集合
-
ConcurrentHashMap:内部进一步细分了若干个小的HashMap,称之为段(Segment),默认情况下,一个ConcurrentHashMap被进一步细分为16个段,如果需要在ConcurrentHashMap中增加一个新的表项,并不是将整个HashMap加锁,而是首先根据hashcode得到该表项应该被存放到哪个段中,然后对该段加锁,并完成put()操作,在多线程环境中,如果多线程同时进行put()操作,只要被加入的表项不存放在同一个段中,则线程间便可以做到真正的并行。可以减小锁粒度。
在复习的过程中阅读了下面这篇博客里的关于JDK1.7与1.8关于ConcurrentHashMap的区别的内容:
-
Collections.synchronizedMap():生成一个名为SynchronizedMap的map,使用委托,将自己所有Map相关的功能交给传入的HashMap实现,自己保证线程安全,使用mutex锁实现同步。
-
Collections.synchronizedList(new LinkedList<>()):同SynchronizedMap类似,线程安全的List。
-
ConcurrentLinkedQueue:高并发环境中性能最好的队列,使用链表作为数据结构,对Node操作采用了CAS操作。
-
CopyOnWriteArrayList:在写入操作时,进行一次自我复制,将修改的内容写入副本中,写完之后,再把副本替换原来的数据,保证写操作不影响读。
-
BlockingQueue:数据共享通道,是一个接口。让服务线程在队列为空时,进行等待,当有新的消息进入队列后,自动将线程唤醒。
主要实现有:ArrayBlockingQueue: 基于数组实现,适合做有界队列,向队列压入元素可以使用offe()和put()方法。对于offer(),如果当前队列已经满了,会立即返回false,如果没有满,则执行正常的入队操作。而put()方法是如果队列满了,他会一直等待,直到队列中有空闲的位置。
类似的从队列中弹出元素,可以使用poll()和take(),他们都从队列的头部获得一个元素。不同之处在于:如果队列为空poll()方法直接放回null,而take()会一直等待,直到队列中有可用元素
AdlayedWorkQueue
DelayQueue
LinkedBolckingQueue:基于链表,适合做无界队列。
PriorityBlockingQueue
SynchronousQueue:
BlockingDeque
ConcurrentSkipListMap:实现了跳表