1.什么是集合?
1.集合就是一个放数据的容器,准确的说,就是放数据集合对象引用的容器;
2.集合存放的都是对象的引用,而不是对象本身;
3.集合类型有三种:Set、List、Map
2.集合的特点
集合的特点主要由以下两点:
1.集合用于存储对象的容器,对象是用来封装数据的,对象多了,也需要存储集中式管理。
2.和数组对比对象的大小不确定。因为集合是可变长度的,数组需要提前定义大小。
3.集合和数组的区别
数组是固定长度的,集合是可变长度的
数组可以存储基本数据类型,也可以存储引用数据类型;集合只能存储引用数据类型
数组存储的元素必须是同一个数据类型;集合存储的对象可以是不同的数据类型
4.常用的集合类有哪些?
Collection接口的子接口包括:Set接口和List接口
Map接口的主要实现类有:HashMap、TreeMap、HashTable、ConcurrentHashMap以及Properties
Set接口的主要实现类有:HashSet、TreeSet、LinkedHashSet等
List接口的主要实现类有:ArrayList、LinkedList
5.List、Set、Map三者的区别是?
6.集合框架底层数据结构
- Collection
- List
- ArrayList:数组
- Vector:数组
- LinkedList:双向循环链表
- Set
- HashSet:基于HashMap实现的,底层采用HashMap来保存元素
- LinkedHashSet:LinkedHashSet继承于HashSet,并且其内部是通过LinkedHashMap来实现的。
- TreeSet:红黑树
- Map
- HashMap:JDK1.8之前是用数组加链表实现的。数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的。JDK1.8之后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为8),将链表转换为红黑树,以减少搜索时间。
- LinkedHashMap:LinkedHashMap继承于HashMap,所以它的底层仍然是基于数组和链表或者红黑树实现。
- HashTable:数组+链表组成的,数组是HashTable的主体,链表则是用来解决哈希冲突的。
- TreeMap:红黑树
7.哪些集合是线程安全的?
Vector、hashTable、ConcurrentHashMap
8.遍历一个 List 有哪些不同的方式?每种方法的实现原理是什么?Java 中 List 遍历的最佳实践是什么?
遍历方式有以下几种:
1.for循环遍历,基于计数器。在集合外部维护一个计数器,然后依次读取每个位置的元素,当读取到最后一个元素后停止。
2.迭代器遍历
3.ForEach循环遍历
最佳实践:
Java Collections框架中提供了一个RandomAccess接口,用来标记List实现是否支持RandomAccess。
如果一个数据集合实现了该接口,就意味着它支持RandomAccess,则使用for循环遍历,否则使用迭代器进行遍历。
9.如何实现数组和List的相互转换?
List<String> list = new ArrayList<>();
list.add("123");
list.add("456");
//将列表转换为数组
String[] strings = (String[]) list.toArray();
//将数组转换为列表
String[] array = new String[]{"123","456"};
List<String> list1 = Arrays.asList(array);
10.多线程场景下使用ArrayList
ArrayList不是线程安全的,如果遇到多线程场景,可以通过Collections的synchronizedList方法将其专为为线程安全的容器再使用
List<String> list = new ArrayList<>();
List<String> synchronizedList = Collections.synchronizedList(list);
synchronizedList.add("123");
synchronizedList.add("456");
for (int i = 0; i < synchronizedList.size(); i++) {
System.out.println(synchronizedList.get(i));
}
11.什么是哈希算法?
哈希算法是指把任意长度的二进制映射为固定长度的较小的二进制,这个较小的二进制值叫做哈希值。
12.什么是链表?
链表是可以将物理地址上线不连续的数据连接起来,通过指针来对物理地址进行操作,实现增删改查的功能。
链表可以分为单向链表和双向链表
单向链表:每个节点包含两部分,一部分是存放数据变量的data,另一部分是指向下一个节点的指针。
双向链表:除了包含单链表的部分,还增加了指向上一个节点的指针
链表的优点:
1.插入删除速度快
2.内存利用率高,不会浪费内存
3.大小没有固定,拓展很灵活。
链表的缺点
不能随机查找,必须从第一个开始遍历,查找效率是比较低的
13.说下HashMap的实现原理
HashMap概述:HashMap是基于哈希表的Map接口的非同步实现。此实现提供所有可选的映射操作,并允许null值的key和null值的value。此类不保证映射的顺序,特别不保证该顺序永久不变
HashMap的数据结构:在Java编程语言中,最基本的结构就两种,一个是数组,另一个是模拟指针(引用)。所有的数据结构都可以用这两种基本结构来构造。HashMap也不例外。HashMap其实就是数组和链表的结合体。
HashMap是基于哈希算法实现的
1.当我们往HashMap中put元素的时候,利用key的哈希值重新计算当前对象的元素在数组中的下标。
2.存储时,如果出现哈希值相同的key值
(1)如果key值相同,则覆盖原来的值
(2)如果key值不同(出现冲突),则将当前的key-value放在链表中。
3.获取时,直接知道哈希值对应的下标,再进一步判断key值是否相同,从而找到对应的值
4.理解了以上过程就不难明白HashMap是如何解决Hash冲突的问题。核心就是使用了数组的存储方式,然后将冲突的key的对象放入链表中,一旦发现冲突就在链表中做进一步的判断。
需要注意的是,jdk1.8中对HashMap的实现做了优化,当链表的节点超过了8个的时候,该链表会转为红黑树来提高查询的效率。