1.什么是集合?
Java集合是存储对象的容器,可以存放不同类型的对象。Java集合框架主要包含两种类型的容器,它们分别是Collection(集合),Map(映射)。其它主要集合类都是由这两种集合接口派生出来的。
2.JAVA常见的集合有哪些?
Java常见的集合类如下图:
List集合是一个有序的,可重复的容器,元素的存入顺序和取出顺序一致。主要实现类有ArrayList, Vector和LinkedList,其中ArrayList和Vector 底层数据结构是数组,LinkedList底层数据结构是双向链表。在线程安全方面,ArrayList和LinkedList 是线程不安全的,Vector是线程安全的。
Set集合是一个不能存放重复元素的容器,主要实现类包括能存放无序且不重复元素的HashSet和能存放有序且不重复元素的LinkedHashSet和TreeSet,其中HashSet是基于HashMap实现的,LinkHashSet是基于LinkHashMap实现的,TreeSet 是基于TreeMap实现的。从线程安全方面来讲,Set集合常用的三种实现都是线程不安全的。
Map集合是一种双列集合容器,其存放数据的方式是类似于Key-Value形式。主要实现类HashMap,LinkHashMap,TreeMap,HashTable。
HashMap在JDK1.8之前底层的数据结构是数组+链表,其中链表主要是为了解决存放对象的hash冲突问题。在JDK1.8之后,为了提升HashMap集合查询效率,其底层数据结构改为数组+链表+红黑树,当链表的长度大于8(默认阈值)是,将链表转为红黑树结构。
LinkedHashMap继承自HashMap,所以其底层数据结构仍然是数组+链表+红黑树,同时为了维护元素的顺序,LinkedHashMap增加了一条双向链表。
LinkedHashMap提供了两种排序方式:按插入顺序排序和按访问顺序排序,按插入顺序排序是指迭代集合元素时,元素的顺序和它最初插入集合的顺序相同。按访问顺序排序是指迭代时元素的顺序和访问它的顺序相同,每次访问元素后(put或者get操作),改元素都会被移动到链表的末尾。
LinkedHashMap 默认是按照插入顺序进行排序的,如果要要创建一个按照访问顺序排序的LinkedHashMap对象可以使用如下代码:
import java.util.LinkedHashMap;
import java.util.Map;
public class Demo {
public static void main(String[] args) {
Map<Integer, String> linkedMap = new LinkedHashMap<>(16, 0.75f,true);
linkedMap.put(1, "张三");
linkedMap.put(2, "李四");
linkedMap.put(3, "王五");
linkedMap.get(2);
for(Map.Entry<Integer, String> entry : linkedMap.entrySet()) {
System.out.println(entry.getKey()+ ":" + entry.getValue());
}
}
}
上边程序的执行结果如下图:
TreeMap 是一个有序的键值对存储容器。它的的底层数据结构是红黑树。
ConcurrentHashMap底层数据结构是基于数组+链表或红黑树的分段锁机制。其内部维护了一个Segment数组,Segment的结构和HashMap很像,每个Segment对象都拥有一个HashEntry数组来存放键值对,当对ConcurrentHashMap对象进行put或者remove操作时,只需要锁定当前Segment即可,这样大大减少了锁的竞争,提高了并发效率。
HashTable是线程安全的键值对集合,他的key和Value不允许有null值。由于使用同步锁Synchronized,元素的操作效率会收到影响。
3.不同集合的应用场景是什么?
1.ArrayList 适用于随机访问元素的场景。
2.LinkedList 适用于频繁插入或删除元素的场景。
3.Vector 和ArrayLIst类似,但是它是线程安全的,适用于多线程场景。但是需要注意的是由于Vector使用的同步锁Synchronized,导致效率十分低下,需谨慎使用。
4.HashSet 适用于不要求元素顺序且元素不能重复的场景。
5.LinkedHashSet适用于要维护元素的插入顺序,且对元素的查找、插入及删除有较高的性能要求的场景。
6.TreeSet使用需要集合中的元素保持一定的顺序的场景,如自然排序或者自定义排序规则等。
7.需要双列容器,同时需要对元素进行快速插入、删除及访问操作,且对元素顺序没有特别要求时,可以使用HashMap。
8.当需要维护元素的插入顺序或访问顺序是,LinkedHashMap是一个很好的选择。
9.ConcurrentHashMap适合于高并发且需要高性能的场景。
10.需要双列容器且需要容器中的元素保持一定的顺序,如自然排序或自定义排序规则时,可以使用TreeMap。
4.集合和数组的区别是什么?
1.数组的长度是固定的,需要在初始化时指定数组长度;而集合的长度是可以变的,当集合中的存储的元素数量达到阈值时,集合会自动扩容。
2.数组既可以存放基本数据类型也可以存放引用数据类型;而集合只能存放引用数据类型。
3.同一个数组只能存放相同数据类型的元素,而集合存储的对象可以是不同的数据类型。