- 说说常见的集合有哪些?
- 实现Collection接口的集合:
- 实现List的集合:
- ArrayList:以数组的类型进行存储,线程不安全,查询效率高,添加删除效率低(因为会对数组中的元素进行移动)
- LinkedList:以双向链表的类型进行存储,线程安全,查询效率低(因为需要双向遍历),添加删除效率高(因为只需要记录前后两个元素)
- vector:以数组的类型进行存储,线程安全,查询效率高,添加删除效率低----------->现在不推荐使用,因为扩容只扩容1倍,而且只能在尾部进行插入与删除,效率太低,所以应使用java.util.concurrent.CopyOnWriteArrayList,也是线程安全的
- stack:vector的子类,特点是先进后出
- 实现set的集合:
- HashSet:无序且不可重复,集合元素可以为null,在进行遍历输出时可能不会按照添加顺序进行输出,重复是通过equals方法判断对象是否相等
- LinkedHashSet:根据元素的HashCode值决定元素存储位置,并且使用双向链表进行维护元素的次序,在进行遍历输出时会按照添加的顺序进行输出。遍历效率比HashSet高,但插入效率比HashSet低
- TreeSet:实现了SortedSet接口,遍历时会将添加的元素排序输出
- 实现Map的接口的集合:
-
- HashMap:以键值对(key,value)的方式进行存储,线程不安全,键值对key、value的值能为null,继承AbstractMap
- HashTable:以键值对(key,value)的方式进行存储,线程安全(所有方法都使用了synchronize修饰),键值对不能为null,继承Dictionary
- TreeMap:以红黑树的类型进行有序的存储,自己可以自定义排序器
- ConcurrentHashMap:线程安全,比HashTable效率高
- HashMap的实现原理?
- HashMap基于hash算法实现的,通过put(key,Value)存储,get(key)获取。当使用put进行存储时,HashMap会根据key的HashCode()计算出的hash值,根据hash值将value存储到bucket中。当计算出存在hash冲突时,HashMap的做法是使用链表和红黑树进行存储相同hash值的value
- HashSet的实现原理?
- HashSet是基于HashMap实现的,HashSet底层使用HashMap来保存所有元素,可以这样说,HashSet中的元素,只是保存在HashMap的key上,而value使用final static的Object对象标识,所以HashSet的实现比较简单,相关的HashSet的操作,基本上是直接调用HashMap中的方法
- HashMap和HashTable之间的区别?
- HashMap:键值对key-value都能为null,线程不安全,继承AbstractMap
- HashTable:键值对key-value不能为null,线程安全,继承Dictionary
- HashTable和ConcurrentHashMap之间的区别?
- HashTable实现线程是为所有的方法加上synchronize的修饰,当有一个线程获得了资源锁,在此线程未释放锁时,其他线程都处于阻塞状态,当存储较大时,效率会急剧下降
- ConcurrentHashMap实现线程是锁的细粒度(分段锁),ConcurrentHashMap将Hash表分为16个桶(默认值),每一把锁只锁容器中的一个桶,多线程访问容器时,就不会存在锁竞争,提高并发访问率
- ConcurrentHashMap是由Segment数组结构和HashEntry数据结构组成。Segment是一种重入锁ReentranLock,扮演锁的角色。HashEntry存储着键值对数据。Segment的结构和HashMap类似,都是数组加链表的存储方式,一个Segment包含一个HashEntry数组,HashEntry数组内存储链表结构的元素,当需要修改HashEntry数组时,必须首先获得对应的Segment。
- HashMap的put()方法的具体流程?
- HashMap在1.8之前的存储方式是【数组+链表】,1.8之后的存储方式是【数组+链表+红黑树】链表长度>8时,链表转为红黑树
- 判断HashMap是否为null或者长度是否为0,如果为null或长度为0,则进行resize()扩容
- resize()扩容是在【length的长度>=[size*扩容因子(0.75)]】时,扩容到原来长度2倍,当长度被扩容到(2^30)时,阈值会被修改为(2^31-1)此后就不会在进行扩容
- 通过key的hash值与HashMap的长度做与运算获取key的索引,判断索引位置是否为null,如果为null,则直接将数据插入
- 如果不为null,则进行判断new key是否与old key相同,并且key!=null,相同,则覆盖旧值
- 如果不相同,则发生了哈希冲突,判断数据结构是树还是链表,是树直接在树中插入或更新
- 如果是链表,则需要对链表进行遍历,判断链表中next位置是否为null
- 如果为null则将数据插入链表,然后进行判断是否链表长度length>=7,满足则转为红黑树,将链表所有元素加入到红黑树中
- 如果不为null,判断new key与old key是否相同,并且key!=null,如果满足,直接覆盖,不满足则继续遍历链表
- 最后判断扩容,当实际存在的键值对数量>最大容量,就进行扩容
- HashMap是如何解决哈希冲突?
- 哈希:也称"散列",任意输入通过哈希函数处理,输出特定长度的值,这就是哈希值
- 哈希函数的特点:哈希冲突:通过统一哈希函数得到相同的哈希值,输入值不相同时,就产生了哈希冲突
- 通过同一哈希函数得到相同的哈希值,输入值不一定相同
- 通过同一哈希函数得到不同的哈希值,输入值一定不相同
- HashMap的存储结构是【数组+链表】,解决哈希冲突的办法就是"链地址法"
- HashMap中indexFor()方法中h&(length-1)是什么意思?
- 此方法主要是为了得到key值的索引,X%2^n=X&(2^n-1),因为HashMap的length默认是16(2^5),扩容操作也是扩容到原来的2倍,而且与操作的效率比较高
- Collection和Collections的区别?
- Collection:是集合类的接口,实现此接口的集合有List和Set
- Collections:是集合类的工具类,提供了一些静态方法实现对各种集合的查询、排序以及线程安全化等操作
- ArrayList、vector、LinkedList的存储性和特性?
- ArrayList和vector都是以数组的方式进行存储,查询效率都很高,插入删除效率因为这两个操作都会涉及数组内元素的移动,所以效率低
- LinkedList:以双向链表的方式进行存储,查询效率低,因为查询时需要双向遍历链表,但是插入和删除的效率高,因为只需要记录前后元素
- 如何实现数组和List之间的转换?
- 数组-->List:Arrays.toList(Array);
- List-->数组:List自带的toArray()方法
- 在Queue中poll()和remove()有什么区别?
- 相同点:都是返回Queue中的第一个元素,并且在Queue中将此元素删除
- 区别:当Queue中没有元素时,poll()会返回null,remove()会抛出异常NoSuchElementException异常
- Array和ArrayList有何区别?
- Array能够存储基本数据类型和对象,ArrayList只能存储对象
- Array是指定大小的,ArrayList是可以自动扩展的
- Array的内置方法没有ArrayList多
- 如何决定使用HashMap还是TreeMap?
- HashMap:当你需要在Map中进行插入、删除和查询操作,因为HashMap效率要高
- TreeMap:当你需要对一个key集合进行排序时
- 集合中的迭代器(Iterator)是什么?它有什么特点?
- Iterator可以遍历任意的Collection接口,在使用一个Collection时可以使用迭代器方法获得迭代器实例。Iterator取代了Java集合框架中的Enumeration,迭代器允许调用者在迭代过程中移除元素(Iterator.remove())
- Iterator的特点:效率比普通的for循环要高,在当前遍历的集合元素被更改的时候(List.remove()、List.add(String str)等),就会抛出ConcurrentModificationException异常,即并发修改异常。详见:https://blog.csdn.net/sukier_JE/article/details/79898892
- Iterator和ListIterator有什么区别?
- Iterator可以遍历Set和List集合,而ListIterator只能遍历List
- Iterator只能单向遍历,而ListIterator可以双向遍历
- ListIterator从Iterator接口继承,解决了并发修改的问题
- 怎么确保一个集合不能被修改?
- 使用Collections.unmodifiableCollection(Collection c)方法来创建一个只读的集合,当对只读集合进行修改时,集合都会抛出java.lang.UnsupportedOperationException异常
Java容器
原文:https://www.cnblogs.com/Fmir/p/11308019.html