二.JAVA【集合】

集合框架的优点?

  1. 使用核心集合类降低开发成本
  2. 复用性和可操作性

集合框架中的泛型有什么优点?

  1. 泛型允许我们为集合提供一个可以容纳的对象类型。因此,如果你添加其他类型的任何元素,会编译错误。这样避免了运行时出现ClassCastException。
  2. 泛型使代码整洁,不需要使用显式的转换和instanceOf操作符。也给运行时带来好处,因为不会产生类检测的字节码指令。

JAVA集合框架的基础接口有哪些?

Collection,为集合层级的根接口。一个集合代表一组对象,这些对象即为它的元素:

  1. Set:是一个不能包含重复元素的集合
  2. List:是一个有序集合,可以包含重复元素。可以使用索引来访问元素。可以把它当做一个长度动态扩容的数组

Map,是一个将key映射到value的对象。一个Map不能包含重复的key,每一个key最多只能映射一个value

还有一些其他的接口,比如:Queue、Dequeue、SortedSet、SortedMap和Listlterator

为什么Map接口不继承Collection接口?

  1. Map不算是集合
  2. 如果Map继承Collection,Map包含key-value对,不适合一组对象规范

Collection和Collections的区别?

  1. Collection,是集合类的上级接口,继承他的主要接口有Set和List
  2. Collections,是针对集合类的一个工具类,它提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作

集合里面的通用算法有哪些?

  1. 排序和搜索
  2. Collections类包含这些方法的实现。大部分算法是操作List的,但是一部分对所有类型的集合都是可用的。部分算法有排序、搜索、混编、最大最小值

集合框架等数据接口

List:

  1. ArrayList:Object数组
  2. Vector:Object数组
  3. LinkedList:双向链表(jdk6之前为循环链表,jdk7取消了循环)

Map:

  1. HashMap:JDK8之前,是由数组+链表组成,数组是HashMap的主题,链表 主要为了解决哈希碰撞而存在的问题
    JDK8之后,在解决哈希冲突有了交大的变化,当链表长度大于阈值(默认为8)时,将链表转化为红黑树,以减少搜索时间
  2. LinkedHashMap:LinkedHashMap继承自HashMap,所有的底层仍然是基于拉链式散列结构即由数组和链表或红黑树组成。另外,LinkedHashMap在上面的结构基础上,增加了一条双向链表,使得上面的接口可以保持键值对的插入顺序。同时通过对链表进行相应的操作,实现了访问顺序相关逻辑
  3. HashTable:数组+链表组成,数组是HashMap的主体,链表是为了解决Hash冲突
  4. TreeMap:红黑树(自平衡的排序二叉树)

Set:

  1. HashSet:无序,唯一,基于HashMap实现,底层采用HashMap来保存元素
  2. LinkedHashSet:继承HashSet,并且其内部是通过LinkedHashMap来实现的
  3. TreeSet:有序,唯一,红黑树

什么是迭代器(Iterator)?

Iterator接口,提供了很多对集合元素迭代的方法。每一个集合类都包含了可以返回迭代实例的迭代方法。迭代器可以在迭代过程中删除底层的元素,但是不可以直接调用集合类的remove方法删除,可以调用迭代器的remove方法删除

Iterator和ListIterator的区别是什么?

  1. Iterator可以用来遍历Set和List集合,但是ListIterator只能用来遍历List
  2. Iterator对集合只能想前遍历,ListIterator可以向前也可以向后
  3. ListIterator继承Iterator接口,并包含其他的功能。比如:增加元素、替换元素,获取前一个元素和后一个元素的索引等等

快速失败(fail-fast)和安全失败(fail-safe)的区别是什么?

差别于ConcurrentModification异常:

  1. 快速失败:当你迭代一个集合的时候,如果有另一个线程正在修改你正在访问的那个集合时,就会抛出一个ConcurrentModification异常。在java.util包下面的都是快速失败的
  2. 安全失败:当你在迭代的时候回去底层集合做一个拷贝,所有在修改上层集合的时候是不会受影响的,不会抛出ConcurrentModification异常。在java.util.concurrent包下的全是安全失败的

如何删除List中的某个元素?

  1. 使用Iterator,顺序向下,如果找到元素,则用remove方法进行删除
  2. 倒序遍历List,如果找到元素,则使用remove方法进行删除

Enumeration和Iterator接口有什么不同?

  1. 相比之下,Enumeration要快2倍,而且占用更少的内存
  2. Iterator更安全,因为其他线程不能修改当前迭代器遍历的集合对象。同时,Iterators允许调用者从底层集合删除元素,Enumeration没法完成

Iterator接口的具体实现

  1. fail-fast代表:ArrayList
  2. fail-safe代表:CopyOnWriteArrayList

Comparable和Comparator的区别?

  1. Comparable接口,在java.lang包下,用于当前对象和其他对象的比较,所以它有一个CompareTo方法用来排序。参数1个
  2. Comparator接口,在java.util包下,用于传入两个对象进行比较,所以有一个compare发方法用来排序。参数2个

List和Set的区别?

List和Sert都继承Collection接口

  1. List特点:元素有序放入,可重复,支n’li持for循环,通过下标遍历也可以用迭代器
  2. Set特点,元素无序放入,不可重复,重复元素会被覆盖,虽然放入无序,但是元素在Set的位置是固定的,由该元素的hashcode决定。只能用迭代进行遍历

List和Set对比:

  1. Set:检索指定元素的效率高,删除和插入效率高,插入和删除可能会引起元素位子改变
  2. List:和数组类似,list可以动态增长,查找指定的元素效率低,插入删除指定的元素效率低,因为可能会引起其他元素位子的改变

如果是随机访问,list会快于set

Array和ArrayList有何区别?什么时候适合用Array?

  1. Array可以容纳基本类型和对象,而ArrayList只能容纳对象
  2. Array是指定大小,而ArrayList大小是固定的,可自动扩容
  3. Array没有提供Arraylist那么多功能,比如addAll、removeAll和iterator等

什么时候更适用Array

  1. 如果列表的大小已固定,大部分情况是存储和遍历
  2. 对于遍历集合数据类型,尽管Collections使用自动装箱来减轻编码任务,在指定大小的基本类型的列表上工作也会变得很慢
  3. 如何你要使用多维数组,使用[][]比list方便

ArrayList和LinkedList区别?

ArrayList:
优点:动态数组,因为地址连续性,存储好了查询操作效率会比较高
缺点:因为地址连续,ArrayList要移动数据,所以插入和删除操作效率比较低

LinkedList:
优点:基于链表的数据结构,地址是任意的,所以在开辟内存空间的时候不需要等一个连续的地址。对于新增和删除操作,比较占优势。适合要头尾操作或插入指定位置的场景
缺点:因为要移动指针,所以查询操作性能比较低

ArrayList和Vector区别?

两者都是数组实现的,主要有3个区别:

  1. Vector很多方法上都有synchronized关键字,是多线程安全的,而ArrayList不是
  2. 两个都采用的线性连续空间来存储元素,但是当空间不足的时候,两个类的增长方式是不同的
  3. Vector可以设置增长因子,而ArrayList不可以

适用场景分析:

  1. 不考虑线程安全的情况下,使用ArrayList效率高,但是实际上如果线程安全的时候使用CopyOnWriteArrayList较多
  2. 如果集合中的元素数目大于集合数组的长度时,在集合中使用数据量比较大的数据,用Vector有一定的优势。这种情况使用linkedList更合适

HashMap和HashTable的区别?

  1. 继承不同:HashTable继承Dictionary,HashMap继承Map接口
  2. HashMap允许空值,HashTable不允许
  3. HashTable线程安全,HashMap线程不安全
  4. HashMap的迭代是快速失败的,而HashTable不是
  5. 扩容不一样。HashMap的扩容每次都是2的指数大小,而HashTable是old*2+1

一般现在不建议使用HashTable,多线程环境下可采用ConcurrentHashMap替代

HashSet和HashMap的区别?

  1. Set是线性结构,值不能重复。HashSet是Set的hashsh实现,Hashset中值不能重复是用HashMap的key来实现的
  2. Map是键值对映射,可以空键空值,HashMap是Map的hash实现,key的唯一性是通过key值hashcode的唯一来确定的,value值则是链表结构,因为不同的key值,可能存在相同的hashcode,所以value值需要是链表结构

他们的共同点就是hash算法实现的唯一性,他们都不能持有基本类型,只能持有对象

HashSet和TreeSet的区别?

b的区别?

  1. HashSet是用一个hash表来实现的,因此,它的元素是无序的。添加,删除的时间复杂度是O(1)
  2. TreeSet是用一个树形结构来实现的,因此,它是有序的。添加、删除的时间fu’za’du
    是O(logn)

对应在Map中插入和删除操作,HashMap是最好的选择
如果需要对一个有序的key进行遍历,TreeSet是最好的选择
基于你的Collection的大小,也许向HashMap中添加元素会更快,然后将HashMap换为TreeMap进行有序的key遍历

HashMap和ConcurrentHashMap的区别?

ConcurrentHashMap是线程安全的HashMap实现。主要区别如下:

  1. ConcurrentHashMap 对整个桶数组进行了分隔分段(segment),然后在每一个分段上都用lock锁进行保护,相对于HashTable的syn关键字锁的粒度更精细了一些,并发性能更好。而 HashMap没有锁机制,不是线程安全的

JDK8之后,ConcurrentHashMap启用了一种全新的方式实现,利用了CAS算法
2. HashMap的键值对允许有null,ConcurrentHashMap不允许

队列和栈是什么,列出他们的区别?

两者都是用来存储数据
1.java.util.queue是一个接口,它的实现类在java并发包中。
队列允许先进先出(FIFO)检索元素
Deque接口允许从两端检索元素
2. 栈和队列相似,但它允许对元素进行后进先出(LIFO)进行检索
Stack是一个扩展自Vecctor的类,而Queue是一个接口

HashMap的工作原理?

Java中最常用的两种结构是数组和模拟指针(引用)。HashMap也是,因此HashMap是一个链表散列,HashMap是基于hasing的原理:

  1. 通过hashcode找到数组中的某一元素
  2. 通过key的equals方法在链表中遍历找到key对应的value

当两个对象的hashcode相同时会发生什么?

  1. 当hashcode相同,所以它们的bucket位置相同,发生了hash碰撞
  2. 因为hashMap使用链表存储对象,这个entry(包含有键值对的Map.Entry对象)会存储在链表中

HashCode和equals方法有何重要性?

HashMap使用key对象的hashcode和equals方法去确定key-value的索引。当我们试着从HashMap中获取值的时候,这些方法会被用到

  1. 如果这两个方法没有正确用到,两个不同的key也许会产生相同的hashcode和equals输出,hashMap会认为它们是相同的,然后覆盖它们,而非把它们存储到不同的地方
  2. 同样的,如果不允许存储重复数据的集合类都使用hashcode和equals去查找重复,所以正确使用它们非常重要,实现应遵循以下规则:

如果o1.equals(o2),那么o1.hashcode()==o2.hashcode(),总是为true
如果o1.hashcode()==o2.hashcode(),并不以为o1.equals(o2)会为true

HashMap的默认容量是多少?

默认是16,负载因子是0.75。也就是HashMap填充了百分75的busket

有哪些顺序的HashMap实现类?

  1. LinkedHashMap,是基于元素进入集合的顺序或者被访问的先后顺序排序
  2. TreeMap,是基于元素的固有顺序。

能否使用任何类做Map的key?

是可以的,但是需要考虑一下几点:

  1. 如果类重写了equals方法,也应该重写hashCode方法
  2. 最好使用不可变更类作为key,这样,hashcode可以被缓存起来,拥有更好的性能,也可以保证未来的hashcode和equals不会改变,因此,String和Integer被作为hashMap的key大量使用

HashMap的长度为什么是2的幂次方?

为了能让HashMap的存取高效,尽量较少碰撞,也就是尽量把数据分配均匀,每个链表/红黑树长度大致相同。
这个算法应该如何设计?
取余操作:
1.取余(%)如果除数是2的幂次方则等价于其除数减一的与(&)操作,也就是(hash%length是leng’t== hash & (length-1) )的前提是length是2的n次方
2. 采用二进制操作&,相对于%能提高运算效率
因此,HashMap的长度时2的幂次方

HashSet的工作原理是什么?

HashSet,当我们创建了一个HashSet对象时,其内部也会创建一个map对象,后续所有的HashSet操作,实际上是基于这个map上的封装

HashSet如何检查重复?

当你把对象加入HashSet时,HashSet会先计算对象的hashcode值来判断对象加入的位置,同事也会与其他加入对象的hashcode值做笔记

  1. 如果没有相同的hashcode,hashset会假设对象没有重复出现
  2. 如果发现有相同的hashcode值的对象,这时会调用equals方法来检测hashcode相同的对象是否真的相同,如果两者相同,hashset就不会让加入操作成功;如果两者不同,hashset就会让加入操作成功

Java Priority Queue是什么?

是一个优先级堆的无界队列,它的元素都以他们的自然顺序有序排列

  1. 在它创建的时候,我们可以提供一个比较器Comparator来负责PriorityQueue中元素的排序
  2. 不允许出现null元素,不允许不提供自然排序的对象,也不允许没有任何关联Comparator的对象
  3. 不是线程安全的,在执行入队和出队操作它需要o(log(n))的时间复杂度

poll和remove方法的区别?

  1. poll方法,在获取元素失败时会返回空
  2. remove方法,失败时会抛出异常

LinkedHashMap和PriorityQueue的区别是什么?

  1. priorityqueue保证最高或者最低优先级的元素总在队列头部,linkedhashmap维持的顺序是元素插入的顺序
  2. 当遍历一个priorityqueue时,没有任何顺序保证,但是linkedhashmao保证遍历顺序就是元素的插入顺序

猜你喜欢

转载自blog.csdn.net/qq_37629227/article/details/112777811