java集合类总结
来源:互联网 发布:淘宝不支持该地区销售 编辑:程序博客网 时间:2024/06/06 03:37
(1)Arraylist与vector区别?
答:arraylist与vector底层实现都是object数组,vector的方法是线程安全的(Synchronized),arraylist不是线程安全的,由于线程的同步影响性能,因此arraylist性能比vector好。
线程安全:如果你的代码所在进程中有多个线程在同时运行,这些线程可能会同时运行这段代码,如果每次运行结果和单线程运行的结果是一样的,而且其他变量的值也和预期的一样,就是线程安全的。
ArrayList每次扩容为原来的1.5倍,扩容时,先复制过来再添加新元素。
(2)HashMap与HashTable区别?
答:HashMap不是线程安全的,HashTable是线程安全的。
HashMap允许key和value为null(hash为0),Hashtable不允许为null。
HashMap中不能用get()方法判断是否存在某个键,应该用containsKey()方法。
()HashMap扩容作用、装载因子(0.75)
答:扩容(避免太多的Hash冲突):
1.元素个数超过阀值 (阀值=数组大小*装载因子)
2.链表转化为红黑树,数组长度小于64的时候
()HashMap的hash原理、数组长度取2的幂次方的原理?
答:
而后与&(数组长度-1),保证哈希值落在数组长度内。当数组长度为2的幂次时(只有一个1),(数组长度-1)与的结果相当于对length取模,同时数组长度为偶数,(数组长度-1)的最后一位为1,可以保证与之后的结果为奇数或偶数,保证散列的均匀性,如果长度为奇数的话,与之后的结果只为偶数,会浪费近一半空间。
()ConcurrentHashMap? 弱一致的
每一项可能是链表,也可能是红黑树,红黑树为了提高查找效率。ConcurrentHashMap允许多个读操作并发执行,读操作不加锁(为了读到最新值,数组引用必须加volatile)。16个写锁
Jdk1.8分段锁:synchronized (虚拟机优化,与ReentrantLock性能差不多)
int Size():返回的是一个不精确的值。统计的时候可能正在插入或删除
过程:basecount+CounterCell[]元素的大致个数。当添加删除元素时,如果countercell为空,说明并发度不高,直接对basecount进行一个cas更新,如果失败,新建一个countercell数组不断进行cas(多次失败和数组会扩容),如果countercell不为空,直接在数组上不断cas。
推荐使用long mappingCount()代替size(),两方法过程一样,只不过返回值不一样。(元素个数可能超过int)
扩容条件:链表转化为红黑树,数组长度小于64的时候
扩容过程:多线程扩容。
Hashtable对整个结构(同步方法)进行加锁,ConcurrentHashMap对每个片段单独加锁,不同桶之间的操作不会相互影响,因此速度快很多。
()SynchronizedMap?SynchronizedList、SynchronizedSet
答:Collections的内部类,包装Map为线程安全的。(Synchronized关键字)
()LinkedHashMap与HashMap的区别?
答:继承HashMap,内部类继承HashMap的内部类(继承key,value和next,同时添加成员域before(指向前驱),after(指向后继)),遍历时可以保证顺序(从head头开始遍历)。(插入顺序或者最近最少使用顺序)
本质是在HashMap的基础上添加了一些类似指针的成员用来保证顺序。
()利用LinkedHashMap实现最近最少使用算法(LRU)
答:继承LinkedHashMap重写如下方法,当元素数量超过缓存的数量时return true即可,当向LinkedHashMap插入元素后,会判断该函数的返回值,判断是否删除最近最少使用的。
例子:
1. //扩展一下LinkedHashMap这个类,让他实现LRU算法
2. class LRULinkedHashMap<K,V> extends LinkedHashMap<K,V>{
3. //定义缓存的容量
4. private int capacity;
5. //带参数的构造器
6. LRULinkedHashMap(int capacity){
7. //调用LinkedHashMap的构造器,传入以下参数
8. super(16,0.75f,true);
9. //传入指定的缓存最大容量
10. this.capacity=capacity;
11. }
12. //实现LRU的关键方法,如果map里面的元素个数大于了缓存最大容量,则删除链表的顶端元素
13. @Override
14. public boolean removeEldestEntry(Map.Entry<K, V> eldest){
15. return size()>capacity;
16. }
17. }
18. //测试类
19. class Test{
20. public static void main(String[] args) throws Exception{
21. //指定缓存最大容量为4
22. Map<Integer,Integer> map=new LRULinkedHashMap<>(4);
23. map.put(9,3);
24. map.put(7,4);
25. map.put(5,9);
26. map.put(3,4);
27. map.put(6,6);
28. //总共put了5个元素,超过了指定的缓存最大容量
29. //遍历结果
30. for(Iterator<Map.Entry<Integer,Integer>> it=map.entrySet().iterator();it.hasNext();){
31. System.out.println(it.next().getKey());
32. }
33. }
34. }
输出结果如下
7
5
3
6
()自己实现LRU
答:链表+队列,当向队列中添加元素时,判断队列中是否存在该元素,如果存在直接移到队头,如果不存在,判断队列是否满,如果不满,直接添加到队头,如果满,添加到队头并删除队尾元素。
()IdentityHashMap
答:底层:Object数组,线性探测法解决冲突。判断key/value相等条件:引用相等。(==)
()WeakHashMap
()EnumMap
()Treemap?
答:底层实现红黑树。
()HashSet
答:实现Set接口,底层实现是HashMap(key为元素值,value恒为Object对象),元素值不允许重复。
()LinkedHashSet
答:底层实现LinkedHashMap
()TreeSet
答:底层实现Treemap
()EnumSet
答:存储同一种枚举类型的实例。根据实例在枚举类型的声明次序,将相应下标的bit置1。枚举实例个数<=64,使用long模拟,>64,使用long[]数组。
(4)Arraylist与LinkedList区别?
答:Arraylist底层实现基于object数组,随机访问元素性能较高。
LinkedList底层基于链表(内部类存储值和前驱后继对象)实现,删除添加元素性能较高。
()集合遍历时动态删除元素?
答:循环中调用集合的remove()方法会出错(size()大小变化),如果想在循环中删除集合中的元素,使用迭代器的remove()方法,因为它不仅删除元素,还正确记录删除后,下一个要迭代的元素。
()ArrayBlockingQueue底层实现(有界)
答:基于数组实现的阻塞队列,当向满队列添加元素或从空队列取元素时,当前线程被阻塞,直到队列有剩余空间或不为空才被唤醒。
()PriorityQueue(无界)-->容量自动增长,非线程安全
答:小顶堆实现。基于自然顺序或者Comparator排序
()DelayQueue
答:在延迟期满时从中取出元素。基于PriorityQueue实现的阻塞队列。
应用:缓存中的对象,超过了有效时间,需要从缓存中移除,使用一个线程
循环查询DelayQueue.
()ArrayDeque
(19)Collection与Collections区别?
答:Collection是java.util下的集合接口,提供了对集合进行基本操作的通用接口方法,Collections是java.util下的工具类,包含了大量用于操作集合的静态方法。
List:元素有序,可重复
Set:元素无序,不可重复
()Iterator与ListIterator的区别?
答:1.Iterator只能向前移动,ListIterator既可以向前也可以向后。
2.Iterator可以遍历Set和List集合,ListIterator只能遍历List。
3.ListIterator实现了Iterator接口,并包含其他功能,如:增加元
素、替换元素等。
()快速失败机制(仅用于检测bug)
答:当多个线程对集合进行结构上的改变时,有可能产生fail-fast机制。迭代器在调用next()、remove()方法时都会调用checkForComodification()方法,该方法主要就是检测modCount == expectedModCount ? 若不等则抛出ConcurrentModificationException异常,从而产生fail-fast机制。(迭代器对象记录的结构改变次数和集合对象记录的结构总改变次数不一样,抛出异常,只有通过迭代器改变结构时,通过赋值会保持两者一致)
()为什么集合类没有实现Cloneable和Serializable接口?
答:克隆或者序列化是跟具体的实现相关的,应该由集合的具体实现类决定如何被克隆或者序列化。
()List与Map区别
答:list存储单列数据,数据有顺序,Map存放双列数据(key、value),数据无顺序。(Map取值:map.get(key) 存值:map.put(key,value))
()CopyOnWriteArrayList --不会抛出ConcurrentModificationException
答:写时复制的容器。当向容器中添加(删除、修改)元素时,不直接向当前容器中添加(删除、修改),而是先将当前容器进行拷贝,复制出一个新的容器,向新容器中添加(删除、修改)元素,添加(删除、修改)完成以后将原容器的引用指向新的容器。
读的时候不需要加锁,不能保证数据的实时一致性,只能保证最终一致性,写的时候加锁,但不妨碍读。
()对集合或者数组进行排序?
两种方法:
1.集合中的对象所属的类实现了java.lang.Comparable接口,然后调用 Collections.sort()或者Arrays.sort()
2.实现java.util.Comparator接口,把实现这个接口的类作为参数传递给上述sort()方法
- java集合类总结
- java集合类总结
- JAVA集合类总结
- java集合类总结
- java集合类总结
- java集合类总结
- JAVA集合类总结
- java集合类总结
- JAVA集合类总结
- java集合类总结
- java集合类总结
- java集合类总结
- java集合类总结
- java集合类总结
- JAVA集合类总结
- java集合类总结
- Java集合类总结
- java集合类总结
- 1.虚拟机
- intelliJ idea 导入eclipse/myeclipse web project
- ubuntu16 caffe安装+测试(cpu)
- Java多线程基础——线程和线程安全
- 决策树算法详解(2)
- java集合类总结
- 关于.gitignore文件使用说明
- HDU 4006-The kth great number
- 【oracle】限定查询与排序显示
- mybatis动态sql参数为实体类时出现的问题
- win7下安装Ubuntu后进不去win7的完美解决方法
- HDU HDOJ 1124 Factorial
- 简单了解生成树协议
- CCF201703-3 Markdown