目录
1.1 collection 与 collections 之间的区别?
1.7 如何决定使用 HashMap 还是 TreeMap ?
2.0 迭代器 Iterator 是什么?怎么使用?有什么特点?
1.1 collection 与 collections 之间的区别?
- Collection是一个集合的接口(集合类的顶级接口)。它提供了对集合对象进行基本操作的的通用的接口方法。Collection接口的意义是为各种具体的集合最大化的统一操作方式,其直接继承接口有List和Set。
- Collections则是集合类的一个工具类/帮助类,其中提供了一系列的静态方法,用于对集合中元素进行排序、搜索以及线程安全等各种操作。
1.2 List、Set、Map之间的区别?
比较 | List | Set | Map |
继承接口 | Collection | Collection | |
常见实现类 | AbstractList(其常用子类:ArrayList、LinkedList、Vector) | AbstractSet(其常用子类:HashSet、LinkedHashSet、TreeSet) | HashMap、HashTable |
元素 | 可重复 | 不可重复(用equals()判断) | 不可重复 |
顺序 | 有序 | 无序(实际上由HashCode决定) | |
线程安全 | Vector线程安全 | HashTable线程安全 |
Collection接口常见的方法:
add()将指定对象添加到集合中
remove()将指定对象从集合中移除
isEmpty()判断当前集合是否为空
contains()判断集合是否包含指定元素
toArray()将此集合转为数组
size()返回此集合中的元素个数
iterator()返回此集合元素上进行迭代的迭代器,用于遍历集合中的对象
1.3 ArrayList和LinkedList的区别?
- ArrayList是基于索引的数据接口,底层是数组,查询快,增删慢; LinkedList底层是链表结构,查询慢,增删快。
- LinkedList 比 ArrayList 更占内存,因为LinkedList为每个节点存储两个引用,一个指向前一个元素,一个指向下一个元素
- 相同点:1.元素有下标、有序、可重复;2.线程不安全
1.4 HashMap 和 HashTable 的区别?
- HashMap 继承 AbstractMap 类,HashTable 继承 Dictionary 类;
- HashMap 是非同步的,线程不安全,HashTable 是同步的,线程安全;HashMap 效率比 HashTable 高;
- HashMap 键值对允许 null ,HashTable 键值对不允许为 null;
- HashMap 中数组初始容量为16,按2倍扩容;HashTable 中数组初始容量为11,按2n+1倍扩容。
1.5 HashMap 的实现原理
HashMap概述:
HashMap是基于哈希表Map接口的非同步实现。此实现提供所有可选的映射操作,并允许键值为null。此类不保证映射的顺序,特别是不保证顺序恒久不变。
HashMap的数据结构:
JDK1.8之前是数组+链表的结构;
JAK1.8之后是数组+链表+红黑树;
HashMap存储实现过程:
(1.8之前)
调用map.put()添加元素时,根据key的hashCode重新计算hash值,根据hash值得到元素位置(即下标),如果该位置为null则直接将元素存放到此数组的该位置上,如果数组该位置上存放其它的元素,则以头插方式、链表形式存放。(头插:新元素从链头插入)
(1.8以后)
- 根据key计算得到key.hash = (h=k.hashCode()) ^ (h>>>16);
- 根据 key.hash 计算得到桶数组的索引 index = key.hash &(table.length-1),找到key的存放位置:
- 如果该位置没有数据,则生成一个节点保存新数据,返回null;
- 如果该位置有数据是一个红黑树,name执行相应的插入/更新操作;
- 如果该位置有数据是一个链表,如果该链表没有该节点,则采用尾插方式新增节点保存新数据,返回null;如果该链表已经有了该节点,那么更新该节点数据,返回旧数据。
当链表长度 >8 ,且数组长度 >64 时,链表会转为红黑树,当链表长度 <6 时,红黑树会重新恢复成链表。
1.6 HashSet 的实现原理
- HashSet 实现 Set 接口,由哈希表(实际上是一个 HashMap 实例)支持。
- HashSet 的底层是 HashMap 。底层使用 HashMap 保存所有的元素,因此其实现基本上都是直接调用底层的 HashMap 的相关方法来完成。
1.7 如何决定使用 HashMap 还是 TreeMap ?
- 对于在 Map 中插入、删除和定位元素这类操作,HashMap 是最好的选择。然而,假如你需要对一个有序的 key 集合进行遍历,TreeMap 是更好的选择。
1.8 实现数组和 List 之间的转换
- List 转 数组 :调用 ArrayList 的 toArray 方法;
- 数组 转 List :调用 Arrays 的 asList 方法。
1.9 哪些集合类是线程安全的?
- Vector :比 ArrayList 多了个同步机制(线程安全),因为效率较低,不太建议使用。
- Stack :堆栈类,后进先出。
- HashTable :比 HashMap 多了线程安全。
- Enumeration :枚举,相当于迭代器。
2.0 迭代器 Iterator 是什么?怎么使用?有什么特点?
- 迭代器是一种设计模式,是一个对象,可以遍历并选择序列中的对象。迭代器通常被称为“轻量级”对象,因为创建它的代价小。Java 中的 Iterator 功能比较简单,只能单向移动:
- 迭代集合步骤:
/**迭代集合步骤:
* 1.获取集合的迭代器 list.iterator();
* 2.判断集合中是否有下一个可迭代的元素 it.hasNext()
* 3.获取当前迭代到的元素 it.next()*/
Iterator<Integer> it = list.iterator();
while(it.hasNext()){
Integer num = it.next();
System.out.println(num);
- Iterator 可以遍历 Set 和 List 集合,但是 ListIterator 只能遍历 List;
- ListIterator 实现了 Iterator 接口,具有更多功能,可以从两个方向遍历 List ,也可以从 List 中插入和删除元素。