5.什么场景下使用list,set,map呢?
如果你经常会使用索引来对容器中的元素进行访问,那么 List 是你的正确的选择。如果你已经知道索引了的话,那么 List 的实现类比如
ArrayList 可以提供更快速的访问,如果经常添加删除元素的,那么肯定要选择LinkedList。
如果你想容器中的元素能够按照它们插入的次序进行有序存储,那么还是 List,因为 List 是一个有序容器,它按照插入顺序进行存储。
如果你想保证插入元素的唯一性,也就是你不想有重复值的出现,那么可以选择一个 Set 的实现类,比如
HashSet、LinkedHashSet 或者 TreeSet。所有 Set
的实现类都遵循了统一约束比如唯一性,而且还提供了额外的特性比如 TreeSet 还是一个 SortedSet,所有存储于 TreeSet
中的元素可以使用 Java 里的 Comparator 或者 Comparable 进行排序。LinkedHashSet
也按照元素的插入顺序对它们进行存储。
如果你以键和值的形式进行数据存储那么 Map 是你正确的选择。你可以根据你的后续需要从 Hashtable、HashMap、TreeMap
中进行选择。
6.区别
(1)ArrayList和LinkedList区别:
a.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
b.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。
c.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。
(2)Vector和ArrayList 区别:
a.Vector的方法都是同步的(Synchronized),是线程安全的(thread-safe),而ArrayList的方法不是,由于线程的同步必然要影响性能,因此,ArrayList的性能比Vector好。
b.当Vector或ArrayList中的元素超过它的初始大小时,Vector会将它的容量翻倍,而ArrayList只增加50%的大小,这样,ArrayList就有利于节约内存空间。
(3)HashSet和TreeSet的区别:
a.TreeSet 是二叉树实现的,Treeset中的数据是自动排好序的,不允许放入null值。 b2.HashSet
是哈希表实现的,HashSet中的数据是无序的,可以放入null,但只能放入一个null,两者中的值都不能重复,就如数据库中唯一约束。
c.HashSet要求放入的对象必须实现HashCode()方法,放入的对象,是以hashcode码作为标识的,而具有相同内容的
String对象,hashcode是一样,所以放入的内容不能重复。但是同一个类的对象可以放入不同的实例 。
(4)HashSet与HashMap的区别:
HashMap | HashSet |
实现了Map接口 | 实现Set接口 |
存储键值对 | 仅存储对象 |
调用put()向map中添加元素 | 调用add()方法向Set中添加元素 |
HashMap使用键(Key)计算Hashcode | HashSet使用成员对象来计算hashcode值,对于两个对象来说hashcode可能相同,所以equals()方法用来判断对象的相等性,如果两个对象不同的话,那么返回false |
HashMap相对于HashSet较快,因为它是使用唯一的键获取对象 | HashSet较HashMap来说比较慢 |
(5)TreeSet和TreeMap的关系
与HashSet完全类似,TreeSet里面绝大部分方法都市直接调用TreeMap方法来实现的。
相同点:
a.TreeMap和TreeSet都是非同步集合,因此他们不能在多线程之间共享,不过可以使用方法Collections.synchroinzedMap()来实现同步。
b.运行速度都要比Hash集合慢,他们内部对元素的操作时间复杂度为O(logN),而HashMap/HashSet则为O(1)。
c. TreeMap和TreeSet都是有序的集合,也就是说他们存储的值都是拍好序的。
不同点:
最主要的区别就是TreeSet和TreeMap分别实现Set和Map接口
TreeSet只存储一个对象,而TreeMap存储两个对象Key和Value(仅仅key对象有序)
TreeSet中不能有重复对象,而TreeMap中value可以存在重复对象。
TreeMap的底层采用红黑树的实现,完成数据有序的插入,排序。
(6)HashMap和HashTable的区别:
a.HashMap是非线程安全的,Hashtable是线程安全的,所以Hashtable重量级一些,因为使用了synchronized关键字来保证线程安全。
b.HashMap允许key和value都为null,而Hashtable都不能为null。 Hashtable继承自 JDK 1.0 的Dictionary 虚拟类,而HashMap是 JDK 1.2 引进的 Map 接口的一个实现。
c.Hashtable和HashMap扩容的方法不一样,Hashtable中数组默认大小11,扩容方式是old*2+1。
d.HashMap中数组的默认大小是16,而且一定是2的指数,增加为原来的2倍。
e.两者通过hash值散列到hash表的算法不一样,Hashtable是古老的除留余数法,直接使用Object的hashcode,而后者是强制容量为2的幂,重新根据hashcode计算hash值,在使用hash和(hash表长度– 1)进行与运算,也等价取膜,但更加高效,取得的位置更加分散,偶数,奇数保证了都会分散到。前者就不能保证。
f. HashMap的迭代器(Iterator)是fail-fast迭代器,而Hashtable的enumerator迭代器不是fail-fast的。所以当有其它线程改变了HashMap的结构(增加或者移除元素),将会抛出ConcurrentModificationException,但迭代器本身的remove()方法移除元素则不会抛出ConcurrentModificationException异常。
List 和 Map 区别?
一个是存储单列数据的集合,另一个是存储键和值这样的双列数据的集合,List 中存储的数据是有顺序,并且允许重复;Map
中存储的数据是没有顺序的,其 key 是不能重复的,它的值是可以有重复的。
Collection 和 Map 的区别:
4.1、Collection 和 Map 的区别 容器内每个为之所存储的元素个数不同。 Collection类型者,每个位置只有一个元素。 Map类型者,持有 key-value pair,像个小型数据库。
各自旗下的子类关系
Collection
List:将以特定次序存储元素。所以取出来的顺序可能和放入顺序不同。
ArrayList / LinkedList / Vector
Set : 不能含有重复的元素
HashSet / TreeSet
Map
HashMap
HashTable
TreeMap
其他特征
List,Set,Map将持有对象一律视为Object型别。Collection、List、Set、Map都是接口,不能实例化。继承自它们的 ArrayList, Vector, HashTable, HashMap是具象class,这些才可被实例化。vector容器确切知道它所持有的对象隶属什么型别。vector不进行边界检查。
总结
如果涉及到堆栈,队列等操作,应该考虑用List,对于需要快速插入,删除元素,应该使用LinkedList,如果需要快速随机访问元素,应该使用ArrayList。
如果程序在单线程环境中,或者访问仅仅在一个线程中进行,考虑非同步的类,其效率较高,如果多个线程可能同时操作一个类,应该使用同步的类。
在除需要排序时使用TreeSet,TreeMap外,都应使用HashSet,HashMap,因为他们 的效率更高。
要特别注意对哈希表的操作,作为key的对象要正确复写equals和hashCode方法。
容器类仅能持有对象引用(指向对象的指针),而不是将对象信息copy一份至数列某位置。一旦将对象置入容器内,便损失了该对象的型别信息。
尽量返回接口而非实际的类型,如返回List而非ArrayList,这样如果以后需要将ArrayList换成LinkedList时,客户端代码不用改变。这就是针对抽象编程。
注意:
1、Collection没有get()方法来取得某个元素。只能通过iterator()遍历元素。
2、Set和Collection拥有一模一样的接口。
3、List,可以通过get()方法来一次取出一个元素。使用数字来选择一堆对象中的一个,get(0)…。(add/get)
4、一般使用ArrayList。用LinkedList构造堆栈stack、队列queue。 5、Map用 put(k,v) /
get(k),还可以使用containsKey()/containsValue()来检查其中是否含有某个key/value。
HashMap会利用对象的hashCode来快速找到key。 6、Map中元素,可以将key序列、value序列单独抽取出来。
使用keySet()抽取key序列,将map中的所有keys生成一个Set。
使用values()抽取value序列,将map中的所有values生成一个Collection。
为什么一个生成Set,一个生成Collection?那是因为,key总是独一无二的,value允许重复。