1.java中的容器有哪些?
java中的容器分为Collection接口和Map接口两类。
Collection接口分为List接口和Set接口。
List接口的实现类有:
- ArrayList
- LinkedList
- Vector 线程安全
- Stack 线程安全
Set接口的实现类有:
- HashSet
- LinkedHashSet
- TreeSet
Map接口的实现类有:
- HashMap
- LinkedHashMap
- TreeMap
- ConcurrentHashMap 线程安全
- HashTable 线程安全
2.谈谈对java集合的理解?
(1)java中的集合框架,主要是由java.util包中的集合接口与实现类组成的。主要包括Collection接口和Map接口以及相关实现类,并且包括Iterator迭代器、Collections等工具类。
(2)Collection接口包括List接口和Set接口。
(3)List是有序集合,元素可以重复,索引从0开始;实现类有ArrayList、LinkedList、Vector。
(4)Set是无序结合,元素不可以重复,Set的实现类有HashSet、TreeSet;其中HashSet是基于Hashmap实现存储的;TreeSet是基于TreeMap实现存储的。
(5)Map是基于键值对存储的,采用key-value键值对方式存储的,key不允许重复,value可以重复。实现类有HashMap、TreeMap、LinkedHashMap、HashTable。
(6)迭代器Iterator接口用于遍历集合,用于遍历List和Set。
(7)Collections是操作集合的工具类,包括排序、搜索、乱序等操作。
3.迭代器Iterator是什么?
Iterator接口提供遍历任何Collection的接口。可以从一个Collection中使用迭代器方法来获取迭代器实例。迭代器取代了java集合框架的Enumeration,迭代器允许调用者在迭代过程中移除元素。
List<String> list=new ArrayList();
Iterator<String> it=list.iterator();
while(it.hasNext()){
String str=it.next();
System.out.print(str);
}
使用迭代器遍历会更加安全,可以保证在当前遍历集合时元素被更改会抛出ConcurrentModificationException异常。
4.List、Set、Map 三者之间的区别?
- List:存储的元素是有序的,可重复
- Set:存储的元素时无序的,不可重复
- Map:使用key-value键值对来存储,key是无序且不可重复的,value可重复,每一个key映射一个value
5.数组和List之间如何转换?
- 数组转List:使用Arrays.asList(array)
- List转数组:使用List自带的toArray()
6.Array和ArrayList的区别?
(1)Array可以存储基本数据类型和对象类型,ArrayList只能存储对象类型
(2)Array是指定固定大小,ArrayList大小可以自动扩展
(3)Array内置方法少于ArrayList,例如addAll、removeAll、iterator
7.ArrayList和LinkedList的区别?
(1)底层数据结构:ArrayList是基于数组实现的,LinkedList是基于双向链表实现的
(2)插入和删除元素:ArrayList采用数组存储,在插入删除时需要移动元素所以性能较差;LinkedList采用链表存储,性能较高
(3)随机访问效率:ArrayList的随机访问效率高,LinkedList是线性存储,需要移动指针来查找元素,随机访问效率低
(4)内存空间占有:ArrayList会预留一定的内存空间,而LinkedList每一个元素需要消耗比ArrayList更多的空间,因为要存放pre+next+data
8.ArrayList和Vector的区别?
(1)初始容量:
- ArrayList的初始容量为0,添加一个元素调整为10
- Vector初始默认容量为10
(2)线程安全:
- ArrayList线程不安全
- Vector 方法使用synchronized关键字修饰,使用了同步锁线程安全
(3)扩容方式:
- ArrayList:在原有基础上扩容0.5倍
- Vector:在原有基础上扩容1倍
(4)执行效率:
Vector的方法都有同步锁,在方法执行时要不断的加锁、解锁,所以性能没有ArrayList高
9.hashCode()或hashCode的作用是什么?
- hashCode()是Object类的本地native方法,底层使用c/c++实现,用于获取该对象的HashCode哈希码
- HashCode哈希码是该对象的内存地址通过哈希Hash算法计算出的一个整数值,代表该对象在哈希表中的位置。主要作用是为了提高查找对象的快捷性,通过HashCode可以快速定位到对象的存储地址。
- 两个对象进行比较,先通过HashCode进行比较,如果相同,再调用equals()进行比较
10.为什么重写equals方法时必须重写HashCode方法?
两种方法之间的关系是:
(1)如果两个对象相同(equals相同,返回true),那么它们的HashCode值一定相同。
(2)如果两个对象的HashCode相同,equals()不一定相同。例如字符串 “通话”,“重地”。
综上所述,在每个覆盖equals方法的类中,也必须覆盖HashCode方法。另外这样也可以避免equals()被频繁调用,减少性能开销
11.HashSet、LikedHashSet和TreeSet的区别?
(1)HashSet是Set的主要实现类,底层是基于HashMap实现的,元素存储无序,可以是Null值且线程不安全
(2)LinkedHashSet是HashSet的子类,存储元素有序,能够按照添加顺序来遍历元素
(3)TreeSet的底层使用红黑树,存储元素有序,可以按照添加顺序来遍历元素,且可以自动进行排序(实现了Comparator接口或Comparable接口)
12.HashSet如何检查重复?
- 当对象加入HashSet时,HashSet会先计算对象的HashCode值来判断对象加入的位置;如果该位置没有其他对象,说明没有重复
- 如果该位置有其他元素,会比较该位置链表内的其他元素的HashCode值
- 如果没有相同的值,代表不重复
- 如果有相同的值,会继续调用equals()方法来判断是否真的相同
- 如果equals()判断结果相同,代表重复;否则代表不重复
13.怎样确保一个集合不被修改?
可以使用Collections.unmodifiableCollection(Collection c)方法来创建一个只读集合,这样改变集合的任何操作就会抛出java.lang.UnSupportedOperationException异常
List<String> list =new ArrayList();
list.add("a");
Collection<String> clist=Collections.unmodifiableCollection(list);
//再添加一个时就会报错
list.add("t");