二 容器
18.java 容器都有哪些?
1)Collection:一个独立元素的序列,这些元素都服从一条或者多条规则。 List必须按照插入的顺序保存元素,而set不能有重复的元素。Queue按照排队规则来确定对象产生的顺序(通常与它们被插入的顺序相同)。
2)Map:一组成对的“键值对”对象,允许你使用键来查找值。
|Collection
| ├List
| │-├LinkedList
| │-├ArrayList
| │-└Vector
| │ └Stack
| ├Set
| │├HashSet
| │├TreeSet
| │└LinkedSet
|
|Map
├Hashtable
├HashMap
└WeakHashMap
19.Collection 和 Collections 有什么区别?
Collection是集合类的上级接口,继承与他有关的接口主要有List和Set
Collections是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全等操作
20.List、Set、Map 之间的区别是什么?
比较 | List | Set | Map |
---|---|---|---|
继承接口 | Collection | Collection | |
常见实现类 | AbstractList(其常用子类有ArrayList、LinkedList、Vector) | AbstractSet(其常用子类有HashSet、LinkedHashSet、TreeSet) | HashMap、HashTable |
常见方法 | add( )、remove( )、clear( )、get( )、contains( )、size( ) | add( )、remove( )、clear( )、contains( )、size( ) | put( )、get( )、remove( )、clear( )、containsKey( )、containsValue( )、keySet( )、values( )、size( ) |
元素 | 可重复 | 不可重复(用equals() 判断) | 不可重复 |
顺序 | 有序 | 无序(实际上由HashCode决定) | |
线程安全 | Vector线程安全 | Hashtable线程安全 | |
21.HashMap 和 Hashtable 有什么区别?
1)它们所继承的类不一样。
HashTable和HashMap都实现了Map接口,但是它们所继承的类时不同的。HashTable继承了Dictionary类(Dictionary类已经过时),而HashMap则是继承了AbstractMap类。我们来看看它们的函数声明。
2)HashTable是线程安全的,HashMap是线程不安全的。
根据JDK6的文档,HashTable是同步的,也就是说,它是线程安全的。从接口的实现中我们就可以看到,Hashtable是实现了Serializable;
HashMap也同样实现了Serializable,但是根据文档所述,HashMap这个类其实是不同步的,也就是说,HashMap是线程不安全的。如果要使用HashMap进行多线程的开发,那么需要手动添加外同步。(可以使用Collections.synchronizedMap(new HashMap())获取一个线程安全的Map)。
3)HashTable不允许null作为key和value,而HashMap允许null作为key和value。
在HashMap中,只能有一条记录使用null作为key(这不是废话嘛 - -!!),但是可以有任意条value为null的记录。意思是,当使用get(key)方法取数据的时候,如果没有,这个key,或者key对应的值为空,那么get(key)返回null。
HashTable和HashMap最大的区别就是这3个了。
最后,HashMap比HashTable拥有更多的方法,也更新。所以尽可能使用HashMap进行开发。
22.如何决定使用 HashMap 还是 TreeMap?
TreeMap<K,V>的Key值是要求实现java.lang.Comparable,所以迭代的时候TreeMap默认是按照Key值升序排序的;TreeMap的实现也是基于红黑树结构。
而HashMap<K,V>的Key值实现散列hashCode(),分布是散列的均匀的,不支持排序;数据结构主要是桶(数组),链表或红黑树。
大多情况下HashMap有更好的性能,所以大多不需要排序的时候我们会使用HashMap.
23.说一下 HashMap 的实现原理?
HashMap的实现原理:
- 利用key的hashCode重新hash计算出当前对象的元素在数组中的下标
- 存储时,如果出现hash值相同的key,此时有两种情况。(1)如果key相同,则覆盖原始值;(2)如果key不同(出现冲突),则将当前的key-value放入链表中
- 获取时,直接找到hash值对应的下标,在进一步判断key是否相同,从而找到对应值。
- 理解了以上过程就不难明白HashMap是如何解决hash冲突的问题,核心就是使用了数组的存储方式,然后将冲突的key的对象放入链表中,一旦发现冲突就在链表中做进一步的对比。
24.说一下 HashSet 的实现原理?
25.ArrayList 和 LinkedList 的区别是什么?
1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。 (LinkedList是双向链表,有next也有previous)
2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。
3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。
26.如何实现数组和 List 之间的转换?
Arrays.asList(strArray);
list.toArray(new String[]{});
27.ArrayList 和 Vector 的区别是什么?
(1)同步性:Vector是线程安全的,用synchronized实现线程安全,而ArrayList是线程不安全的,如果只有一个线程会访问到集合,那最好使用ArrayList,因为它不考虑线程安全,效率会高些;如果有多个线程会访问到集合,那最好是使用Vector,因为不需要我们再去考虑和编写线程安全的代码。
(2)数据容量增长:二者都有一个初始容量大小,采用线性连续存储空间,当存储的元素的个数超过了容量时,就需要增加二者的存储空间,Vector增长原来的一倍,ArrayList增加原来的0.5倍。
28.Array 和 ArrayList 有何区别?
Array可以包含基本类型和对象类型,ArrayList只能包含对象类型
Array大小固定,ArrayList的大小是动态变化的。
ArrayList提供了更多的方法和特性:比如 :addAll(),removeAll(),iterator()等等。
29.在 Queue 中 poll()和 remove()有什么区别?
- queue的增加元素方法add和offer的区别在于,add方法在队列满的情况下将选择抛异常的方法来表示队列已经满了,而offer方法通过返回false表示队列已经满了;在有限队列的情况,使用offer方法优于add方法;
- remove方法和poll方法都是删除队列的头元素,remove方法在队列为空的情况下将抛异常,而poll方法将返回null;
- element和peek方法都是返回队列的头元素,但是不删除头元素,区别在与element方法在队列为空的情况下,将抛异常,而peek方法将返回null.
30.哪些集合类是线程安全的?
Vector:就比Arraylist多了个同步化机制(线程安全)。
Hashtable:就比Hashmap多了个线程安全。
ConcurrentHashMap:是一种高效但是线程安全的集合。
Stack:栈,也是线程安全的,继承于Vector
31.迭代器 Iterator 是什么?
为了方便的处理集合中的元素,Java中出现了一个对象,该对象提供了一些方法专门处理集合中的元素.例如删除和获取集合中的元素.该对象就叫做迭代器(Iterator).
对 Collection 进行迭代的类,称其为迭代器。还是面向对象的思想,专业对象做专业的事情,迭代器就是专门取出集合元素的对象。但是该对象比较特殊,不能直接创建对象(通过new),该对象是以内部类的形式存在于每个集合类的内部。
1.Iterable
正是由于每一个容器都有取出元素的功能。这些功能定义都一样,只不过实现的具体方式不同(因为每一个容器的数据结构不一样)所以对共性的取出功能进行了抽取,从而出现了Iterator接口。而每一个容器都在其内部对该接口进行了内部类的实现。也就是将取出方式的细节进行封装。
32.Iterator 怎么使用?有什么特点?
33.Iterator 和 ListIterator 有什么区别?
34.怎么确保一个集合不能被修改
Java中提供final关键字,对基本类型进行修饰,当第一次初始化后,该变量就不可被修改
然而,对于Map等类型,我们只能对于其引用不能被再次初始化,而其中的值则可以变化
改进方法(通过Collectionsf方法):static {
map.put(1, "one");
map.put(2, "two");
map = Collections.unmodifiableMap(map);
}