Collection
├List
│├LinkedList
│├ArrayList
│└Vector
│ └Stack
└Set
Map
├Hashtable
├HashMap
└WeakHashMap
Map map = new HashMap();
Iterator iter = map.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
Object key = entry.getKey();
Object val = entry.getValue();
}
HashMap<String , Double> map = new HashMap<String , Double>();
map.put("语文" , 80.0);
map.put("数学" , 89.0);
map.put("英语" , 78.2);
import java.util.*;
class HashMapDemo {
public static void main(String args[]) {
// Create a hash map
HashMap hm = new HashMap();
// Put elements to the map
hm.put("John Doe", new Double(3434.34));
hm.put("Tom Smith", new Double(123.22));
hm.put("Jane Baker", new Double(1378.00));
hm.put("Todd Hall", new Double(99.22));
hm.put("Ralph Smith", new Double(-19.08));
// Get a set of the entries
Set set = hm.entrySet();
// Get an iterator
Iterator i = set.iterator();
// Display elements
while(i.hasNext()) {
Map.Entry me = (Map.Entry)i.next();
System.out.print(me.getKey() + ": ");
System.out.println(me.getValue());
}
System.out.println();
// Deposit 1000 into John Doe's account
double balance = ((Double)hm.get("John Doe")).doubleValue();
hm.put("John Doe", new Double(balance + 1000));
System.out.println("John Doe's new balance: " +
hm.get("John Doe"));
}
}
List<String> list = new ArrayList<String>();
list.add("luojiahui");
list.add("luojiafeng");
//方法1
Iterator it1 = list.iterator();
while(it1.hasNext()){
System.out.println(it1.next());
}
//方法2 怪异!
for(Iterator it2 = list.iterator();it2.hasNext();){
System.out.println(it2.next());
}
//方法3
for(String tmp:list){
System.out.println(tmp);
}
//方法4
for(int i = 0;i < list.size(); i ++){
System.out.println(list.get(i));
}
在Java中,容器类库部分主要包含两个基本的概念:Collection和Map。其中Collection是一个对象序列,用以“保存对象”。Map是一组成对的“键值对”对象,允许使用键来查找值。
首先讲一下Collection。在Java容器类库部分,Collection接口是序列的总接口。其下有3个功能各不相同的子接口:List、Set和Queue。它们的作用各不相同:List必须按照插入的顺序保存元素、Set不能有重复元素、Queue按照队列规则确定对象的产生顺序。下面分别介绍着三个子接口:
- List:list接口主要有两个常用的实现类:ArrayList和LinkedList。ArrayList基于数组实现,LinkedList基于链表实现。根据二者的实现机制不同,体现了操作上性能的不同,故而各有各自的应用场合。ArrayList长于随机访问元素,但是在List中插入和移动元素时较慢;LinkedList插入和删除操作比较快,但是随即访问方面比较慢。
- Set:Set不允许保存重复元素。Set最常被使用的是测试归属性,可以很容易的测试某个对象是否在这个集合中。通常选择HashSet,它专门对快速超找进行了优化。Set主要分为两类:系统内部维持顺序的set和排序的set(SortedSet)。下面讲一下Set常用的三个实现类:HashSet、TreeSet和LinkedHashSet。HashSet是为了快速查找而设计,存入HashSet内的元素必须实现hashcode()方法;LinkedHashSet同样具有HashSet的查找速度,且内部使用链表来维持元素的插入顺序,这个Set中的元素也必须实现hashcode()方法;TreeSet是SortedSet的唯一实现。它能够按照大小来保持其中元素的顺序。底层结构为红黑树结构,存入其中的元素必须实现Comparable接口。HashSet和LinkedHashSet的底层结构都采用了散列函数。
- Queue:在Java SE5中,Queue仅有两个具体实现:LinkedList和PriorityQueue。其中LinkedList上面也已经介绍过,它有双向队列的功能。PriorityQueue是根据优先级进行排队的队列,其中接收的元素必须实现Comparable接口。
接下来讲一下Map。Map可以成为映射表或关联数组。它的基本思想是维护键-值关联。可以使用键来查找值。关于Map的基本实现,主要有如下几种:HashMap、TreeMap、LinkedHashMap、WeakHashMap、ConcurrentHashMap和IndentityHashMap。下面主要介绍一下前三种:
- HashMap:基于散列表的实现。插入和查询“键值对”的开销是固定的。可以通过构造器来指定初始容量和负载因子以调整容器的性能。(容量:散列表的桶数;尺寸:当前存储的项数;负载因子:尺寸/容量。负载轻的表产生冲突的可能性小(空表负载0,半满表负载0.5),因此对插入和查找都是最理想的(但会减慢迭代速度)。当达到负载因子的水平时,容器将自动增加容量(桶数),并重新将现有对象分布到新的桶位集中)。
- LinkedHashMap:类似于HashMap,但迭代时保持插入顺序。查找比HashMap慢一点,但有更快的迭代速度,因为使用链表维持内部顺序。
- TreeMap:基于红黑树的实现,查看键或键值对的时候会被排序(次序由Comparable或Comparator决定)
上面分别介绍了容器类库中的几个主要容器类,下面介绍一下如何选择使用容器类:
- 选择List:对于插入操作:ArrayList,当列表变大时,其开销将变得很昂贵,而LinkedList相对低廉。最佳的做法是将ArrayList做为默认首选,只有需要使用额外的功能,或是程序的性能因为经常从表中进行插入和删除而变差的时候,才去选择LinkedList。
- 选择Set:HashSet的性能基本上总是好于TreeSet。只有在需要维持元素的排序状态或经常执行迭代操作时,才选择TreeSet。对于插入操作,因为LinkedList需要维持列表,所以开销会大一些。
- 选择Map:第一选择是HashMap,只有需要顺序的时,才使用TreeMap。LinkedHashMap在插入时要比HashMap慢一些,因为它要维持链表以保证插入顺序。正因为LinkedHashMap有保持顺序的链表,所以它的迭代速度更快。