Java集合

来源:互联网 发布:C语言干什么的 编辑:程序博客网 时间:2024/06/03 21:32
HashMap HashTable List ArrayList Set
  
HashMap和HashTable的区别
HashMap的实现原理,key的hash算法
哪些集合是有序的(List)?哪些是无序的(Set、HashMap)?
  
ArrayList的线程安全问题,一个线程在读,一个线程在写会怎么样?它是线程安全的吗?
  
HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,
主要区别在于HashMap允许空(null)键值(key),由于非线程安全,效率上可能高于Hashtable。

HashMap允许将null作为一个entry的key或者value,而Hashtable不允许。

HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因为contains方法容易让人引起误解。 

Hashtable继承自Dictionary类,而HashMap是Java1.2引进的Map interface的一个实现。

最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多个线程访问Hashtable时,不需要自己为它的方法实现同步,
而HashMap 就必须为之提供外同步(Collections.synchronizedMap)。 

Hashtable和HashMap采用的hash/rehash算法都大概一样,所以性能不会有很大的差异。
(HashMap不是线程安全的,但其在单线程程序中的性能比HashTable要高,HashTable支持线程同步保证线程安全而导致性能下降)


Collection是最基本的集合接口

不论 Collection 的实际类型如何,它都支持一个 iterator() 的方法,该方法返回一个迭代子,

使用该迭代子即可逐一访问 Collection 中每一个元素
Collection 接口派生的两个接口是 List 和 Set。
Collection 接口提供的主要方法: 
boolean add(Object o) 添加对象到集合; 
boolean remove(Object o) 删除指定的对象; 
int size() 返回当前集合中元素的数量; 
boolean contains(Object o) 查找集合中是否有指定的对象; 
boolean isEmpty() 判断集合是否为空; 
Iterator iterator() 返回一个迭代器; 
boolean containsAll(Collection c) 查找集合中是否有集合 C 中的元素; 
boolean addAll(Collection c) 将集合 C 中所有的元素添加给该集合; 
void clear() 删除集合中所有元素; 
void removeAll(Collection c) 从集合中删除 C 集合中也有的元素; 

void retainAll(Collection c) 从集合中删除集合 C 中不包含的元素。

---

所有类都在 java.util 这个包里
  Collection
├List
├LinkedList
├ArrayList
│Vector
  └Stack
└Set
  Map
├Hashtable
├HashMap
└WeakHashMap

List接口是有序的Collection,List 允许有相同的元素

Map 没有继承 Collection 接口。Map 提供 Key 到 Value 的映射,一个 Map 中不能包含相同的 Key,
每个 Key 只能映射一个 Value。Map 接口提供 3 种集合的视图,Map 的内容可以被当作一组 Key 集合,一组 Value 集合,
或者一组 Key-Value 映射。 
Map 提供的主要方法: 
boolean equals(Object o) 比较对象; 
boolean remove(Object o) 删除一个对象; 
put(Object key,Object value) 添加 key 和 value。

集合最多能放多少元素?跟机器的内存有关,只要内存没有溢出,理论上可以放无限个。????

HashMap能放多少元素? 2147483647(2^31-1) ,也就是Int的最大值,HashMap在不考虑Hash冲突的情况下也一样。

正解,如过考虑Hash冲突,由于HashMap使用“数组+链表”的方式存储数据,一个HashMap最多可以有(2^31-1)个链表.

一个链表可以包含多少个元素?由于64bit JVM的引用类型长度(可以)为8字节,所以一个链表最多可以存放(2^63-1)个元素。

HashMap,可以存放的最多元素是:(2^31-1)*(2^63-1)个? 当然不是。一个JVM虚拟机里最多只能存在(2^63-1)个对象!!!
原因前面已说,因为应用类型的长度为8字节。

由于JVM启动起来已经生成了很多对象,所以实际上我们写代码也不可能new(2^63-1)这么多个对象。

上面没有考虑JVM实际上能使用多少内存,一个对象至少占用16字节,加上上引用8字节就是24字节了。
所以实际上JVM能分配出来的对象远没有那么多。

-->使用for循环与使用迭代器iterator的对比

效率上的各有有事

采用ArrayList对随机访问比较快,而for循环中的get()方法,采用的即是随机访问的方法,因此在ArrayList里,for循环较快

采用LinkedList则是顺序访问比较快,iterator中的next()方法,采用的即是顺序访问的方法,因此在LinkedList里,使用iterator较快

从数据结构角度分析,for循环适合访问顺序结构,可以根据下标快速获取指定元素.而Iterator 适合访问链式结构,
因为迭代器是通过next()和Pre()来定位的.可以访问没有顺序的集合.

而使用 Iterator 的好处在于可以使用相同方式去遍历集合中元素,而不用考虑集合类的内部实现
(只要它实现了 java.lang.Iterable 接口),如果使用 Iterator 来遍历集合中元素,一旦不再使用 List 转而使用 Set 来组织数据,
那遍历元素的代码不用做任何修改,如果使用 for 来遍历,那所有遍历此集合的算法都得做相应调整,因为List有序,Set无序,
结构不同,他们的访问算法也不一样.
0 0