集合与映射

  • 集合框架概述

集合就是将若干用途,性质相同或相见的数组合成一个整体.

从体系上讲,集合类型可以归纳为三种:

  • 集(Set):Set集合中不区分元素的顺序,不允许出现重复元素.
  • 列表(List):List集合区分元素的顺序,且允许包含重复元素.
  • 映射(Map):映射中保存成对的"键-值"(Key-Value)信息,映射中不能包含重复的键,每个键最多只能映射一个值.
  • java集合中能保存引用类型的数据,实际上存放的对象时引用,而非对象本身,集合中元素相当于引用类型变量

Collection接口

java.util.Collection接口是描述Set和List集合类型的根接口,其中定义了有关集合操作的普遍性方法:

  • boolean add(Object o)
  • boolean remove(Object o)
  • int size()
  • boolean isEmpty()
  • boolean contains(Object o)
  • void clear()
  • Iterator iterator()
  • Object[] toArray()

Set和List接口

  • java.util.Set和java.util.List分别描述前述的集合列表结构,二者均为Collection的子接口。
  • List接口规定使用者可以对列表元素的插入位置进行精确控制,并添加了根据元素索引来访问元素等功能,接口中新天津了相应的方法:
  • void add(int index,Object element)
  • Object get(int index)
  • Object set(int index,Object element)
  • int indexOf(Object o)
  • Object remove(int index)

Map接口

java.util.Map接口描述了映射结构,Map结构允许以键集、值集合或键-值映射关系集的形式查看某个映射的内容.

主要方法:

  • Object put(Object key,Object value)
  • Object get(Object key)
  • boolean isEmpty()
  • void clear()
  • int size()
  • boolean containsKey(Object key)
  • boolean containsValue(Object value)
  • Set keySet()
  • Collection values()

集合相关API关系结构

ArrayList

  • java.util.ArrayList类实现了List接口,用于表述长度可变的数组列表
  • ArrayList列表允许元素取值为null,除实现了List接口定义的所有功能外,还提供了一些方法来操作列表容量的大小,相关方法包括:
  • public ArrayList()
  • public ArrayList(int initialCapacity)
  • public void ensureCapacity(int minCapacity)
  • public void trimToSize()
import java.util.Date;
import java.util.ArrayList;

public class TestArrayList{
	public static void main(String[] args) {
		ArrayList h = new ArrayList();
		h.add("1st");
		h.add("2nd");
		h.add(new Integer(3));
		h.add(new Double(4.0));
		h.add("2nd");      // 重复元素, 加入
		h.add(new Integer(3)); // 重复元素,加入
		System.out.println(h);		
		System.out.println("size=" + h.size());
		System.out.println("-----替换指定元素-----");	
		h.set(3,"replace");		
		System.out.println("-----for循环遍历-----");
		for(int i=0;i<h.size();i++){
			System.out.println(h.get(i));
		}		
		System.out.println("-----取用特定元素-----");		
		Integer it = (Integer)h.get(2);
		System.out.println(it.intValue());
		System.out.println("-----插入元素-----");		
		h.add(3,new Date());
		System.out.println("-----转换为数组-----");	
		Object[] os = h.toArray();
		for(Object o : os){
			System.out.println(o);	
		}		
	}
}

 Vector

java.util.vector也实现了List接口,其描述的也是可变长度的对象数组.

与ArrayList的差别:Vector是同步(线程安全)的,运行效率要低一些,主要用在多线程环境中,而ArrayList是不同步的,适合在单线程环境中使用。

常用方法(除实现List接口中定义的方法外):

  • public vector()
  • public Object elementAt(int index)
  • public void addElement(Object obj)
  • public void removeElementAt(int index)
  • public void insertElementAt(E obj,int index)
  • public boolean removeElement(Object obj)
  • public void removeAllElements()
  • public Object[] toArray()
import java.util.Date;
import java.util.Vector;

public class TestVector{
	public static void main(String[] args) {
		Vector v = new Vector();
		v.add("1st");
		v.add("2nd");
		v.add(new Integer(3));
		v.add(new Double(4.0));
		v.add("2nd");      // 重复元素, 加入
		v.add(new Integer(3)); // 重复元素,加入
		System.out.println(v);		
		System.out.println("size=" + v.size());
		System.out.println("-----替换指定元素-----");	
		v.set(3,"replace");		
		System.out.println("-----for循环遍历-----");
		for(int i=0;i<v.size();i++){
			System.out.println(v.get(i));
		}		
		System.out.println("-----取用特定元素-----");		
		Integer it = (Integer)v.get(2);
		System.out.println(it.intValue());
		System.out.println("-----插入元素-----");		
		v.add(3,new Date());
		System.out.println("-----转换为数组-----");	
		Object[] os = v.toArray();
		for(Object o : os){
			System.out.println(o);	
		}		
	}
}

 

Stack

java.util.Stack类继承了Vector类,对应数据结构中以"后进先出"(Last in First out,LIFO)方式存储和操作数据的对象栈.

Stack类提供了常规的栈操作方法:

  • public Stack()
  • public Object push(E item)
  • public Object pop()
  • Public Object peek()
  • public boolean empty()
  • public void clear()
  • public int search(Object o)
import java.util.Date;
import java.util.Stack;

public class TestStack{
	public static void main(String[] args) {
		Stack s = new Stack();
		s.push("hello");
		s.push(new Date());
		s.push(400);  //自动封装,等价于s.push(new Integer(400));
		s.push(3.14);
		
		System.out.println("弹栈前:size=" + s.size());
		System.out.println(s.pop());
		System.out.println("弹栈后:size=" + s.size());
		System.out.println(s.peek());
		System.out.println("peek操作后:size=" + s.size());
		while(!s.isEmpty())
			System.out.println(s.pop());
	}
}

 Iterator接口

java.util.Iterator接口描述的是以统一方式对各种集合进行遍历/迭代的工具,也称"迭代器".

允许在"遍历"过程中移除结合中的(当前遍历到的那个)元素.

主要方法:

  • boolean hasNext()
  • Object next()
  • void remove()
import java.util.Date;
import java.util.ArrayList;
import java.util.Vector;
import java.util.Iterator;

public class TestIterator{
	public static void main(String[] args) {
		ArrayList a = new ArrayList();
		a.add("China");
		a.add("USA");
		a.add("Korea");
		Iterator  it = a.iterator();
		while(it.hasNext()){
			String country = (String)it.next();
			System.out.println(country);	
		}		
		
		Vector v = new Vector();
		v.addElement(new Date());	
		v.addElement(new Date(200008755554L));
		it = v.iterator();
		while(it.hasNext()){
			Date time = (Date)it.next();
			System.out.println(time);	
		}			
	}
}

 HashSet

  • java.util.HashSet类实现了java.util.Set接口,描述典型的Set集合结构
  • HashSet中不允许出现重复元素,不保证集合中元素的顺序
  • HashSet中允许包含值为null的元素,但最多只能有一个null元素。
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;

public class TestHashSet{
	public static void main(String[] args) {
		HashSet h = new HashSet();
		h.add("1st");
		h.add("2nd");
		h.add(new Integer(3));
		h.add(new Double(4.0));
		h.add("2nd");      	// 重复元素, 未被加入
		h.add(new Integer(3)); 	// 重复元素,未被加入
		h.add(new Date()); 
		System.out.println("开始: size=" + h.size());
		Iterator it = h.iterator();
		while(it.hasNext()){
			Object o = it.next();
			System.out.println(o);	
		}
		
		h.remove("2nd");
		System.out.println("移除元素后: size=" + h.size());
		System.out.println(h);
	}
}

 TreeSet

  • java.util.TreeSet类也实现了java.util.Set,它描述的是Set的一种变体——可以显示排序的集合。
  • 在将对象元素添加到TreeSet集中时会自动按照某种比较规则将其插入到有序的对象序列中,以保证TreeSet集合元素组成的对象序列时刻按照"升序"排列.
import java.util.TreeSet;
import java.util.Iterator;

public class TestTreeSet{
	public static void main(String[] args) {
		TreeSet ts = new TreeSet();
		ts.add("orange");
		ts.add("banana");
		ts.add("apple");
		ts.add("grape");

		Iterator it = ts.iterator();
		while(it.hasNext()){
			String fruit = (String)it.next();
			System.out.println(fruit);	
		}
	}
}

 Comparable接口

  • java.lang.Comparable接口中定义的compareTo()方法用于提供对其实现类的对象进行整体排序所需的比较逻辑。
  • 实现类基于compareTo()方法的排序被称为自然排序,而compareTo()方法被称为它的自然比较方法,具体的排序原则可由实现类根据需要而定
  • 用户在重新compareTo()方法以定制比较逻辑时,需要确保与等价性质判断方法equals()保持一致。
public class Person implements java.lang.Comparable{
	private final int id;
	private String name;
	private int age;
	
	public Person(int id,String name,int age){
		this.id = id;
		this.name = name;
		this.age = age;	
	}
	public int getId(){
		return id;	
	}
	public void setName(String name){
		this.name = name;
	}
	public String getName(){
		return name;	
	}
	public void setAge(int age){
		this.age = age;	
	} 
	public int getAge(){
		return age;	
	}
	public String toString(){
		return "Id: " + id + "\tName: " + name + "\tAge: " + age; 	
	}	
	@Override
	public int compareTo(Object o){
		Person p = (Person)o;
		return this.id - p.id;		
	}
	@Override
	public boolean equals(Object o){
		boolean flag = false;
		if(o instanceof Person){
			if(this.id == ((Person)o).id)
				flag = true;
		}
		return false;		
	}	
}
import java.util.TreeSet;
import java.util.Iterator;

public class TestComparable{
	public static void main(String[] args) {
		TreeSet ts = new TreeSet();
		ts.add(new Person(1003,"张三",15));
		ts.add(new Person(1008,"李四",25));
		ts.add(new Person(1015,"王五",73));
		ts.add(new Person(1001,"赵六",49));

		Iterator it = ts.iterator();
		while(it.hasNext()){
			Person employee = (Person)it.next();
			System.out.println(employee);	
		}
	}
}

 HashMap

  • java.util.HashMap类实现了java.util.Map接口,该类基于哈希表实现了前述的映射集合结构。
  • HashMap结构不保证其中元素(映射信息)的先后顺序,并且允许使用null"值"和"null"键.
  • 当集合中不存在当前检索的"键"所对应的映射值时,HashMap的get()方法会返回null,而不会运行出错.
  • 影响HaspMap性能的两个参数:
  • 初始容量(Inital Capacity)
  • 加载因子(Load Factor)
import java.util.Set;
import java.util.HashMap;
import java.util.Collection;
import java.util.Iterator;

public class TestHashMap{
	public static void main(String[] args) {
		HashMap hm = new HashMap();
		hm.put(new Integer(1003),new Person(1003,"张三",15));
		hm.put(new Integer(1008),new Person(1008,"李四",25));
		hm.put(1015,new Person(1015,"王五",73));   //自动封装
		hm.put(1001,new Person(1001,"赵六",49));

		System.out.println("----检索单个元素----");
		Person p = (Person)hm.get(1008);
		System.out.println(p);
		
		System.out.println("----遍历所有\"键\"(元素名)----");
		Set names = hm.keySet();
		for(Object o : names){
			System.out.println(o);
		}
		
		System.out.println("----遍历所有\"值\"(元素值)----");
		Collection values = hm.values();
		for(Object o : values){
			System.out.println(o);
		}
	}
}

Hashtable 

 java.util.Hashtable与HashMap作用基本相同,也实现了Map接口,采用了哈希表的方式将"键"映射到哦相应的"值".

Hashtable 与HashMap的差别:

  • Hashtable中元素的"键"和"值"均不允许为null,而HashMap则允许
  • Hashtable是同步的,即线程安全的,效率相对要低一些,适合在多线程环境下使用;而HashMap是不同步的,效率相对高一些,提倡在单线程环境中使用.
  • Hashtable与HashMap的用法格式完全相同.

TreeMap

  • java.util.TreeMap类实现了将Map映射中的元素按照"键"进行升序排列的功能,其排序规则也可以是默认的按照"键"的自然顺序排序,也可以使用指定的其他排序规则.
  • 向TreeMap映射中添加的元素"键"所属的类必须实现Comparable接口

Enumeration接口

java.util.Enumeration接口作用与Iterator接口类似,但只提供了遍历Vector和Hashtable(及子类Properties)类型集合元素的功能

Collections类

java.util.Collections类中定义了多种集合操作方法,实现了对集合元素的排序,取极值,批量拷贝,集合结构转换,循环移位以及配性检查等功能:

主要方法:

  • public static void sort(List list)
  • public static void reverse(List list)
  • public static void shuffle(List list)
  • public static void copy(List dest,List src)
  • public static ArrayList list(Enumeration e)
  • public static int frequency(Collection c,Object o)
  • public static T max(Collection coll)
  • public static T min(Collection coll)
  • public static void rotate(List list,int distance)
import java.util.Vector;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;

public class TestCollections{
	public static void main(String[] args) {
		ArrayList alist = new ArrayList();
		alist.add(75); 
		alist.add(38); 
		alist.add(21); 
		alist.add(4); 
		alist.add(12); 

		System.out.println("原列表: " + alist);
		Collections.sort(alist);
		System.out.println("排序后: " + alist);
		Collections.reverse(alist);
		System.out.println("逆序后: " + alist);
		Collections.shuffle(alist);
		System.out.println("混排后: " + alist);
		Collections.rotate(alist,2);
		System.out.println("移位后: " + alist);		
		
		ArrayList blist = new ArrayList();
		blist.add(55); 
		blist.add(66);
		System.out.println("新列表: " + blist);
		Collections.copy(alist,blist);
		System.out.println("拷贝后: " + alist);

		System.out.println("列表中出现元素66的次数: " + Collections.frequency(alist,66));
		System.out.println("列表中元素的最大值: " + Collections.max(alist));
		System.out.println("列表中元素的最小值: " + Collections.min(alist));

		Enumeration en = createDemoEnumeration();
		ArrayList clist = Collections.list(en);
		System.out.println("Enumeration->ArrayList: " + alist);
	}
	
	public static Enumeration createDemoEnumeration(){
		Vector v = new Vector();
		v.add("Tom");		
		v.add("Billy");		
		v.add("Jenny");		
		return v.elements();	
	}
}

 Arrays类

java.util.Arrays类定义了多种数组操作方法,实现了对数组元素的排序,填充,转换为列表或字符串形式,增强的检索和深度比较等功能.

主要方法:

  • public static List asList(Object... a)
  • public static  void sort(<类型>[] a)
  • public static int binarySearch(int[] a,int key)
  • public static String toString(int[] a)
import java.util.List;
import java.util.Arrays;

public class TestArrays{
	public static void main(String[] args) {
		Integer[] a = {3,25,12,79,48};
		System.out.println(a);
		System.out.println(Arrays.toString(a));
		Arrays.sort(a);
		System.out.println(Arrays.toString(a));
		int idx = Arrays.binarySearch(a,25);
		System.out.println(idx);
		
		List list = Arrays.asList(3,4,5);
		System.out.println(list);
		list.set(2,66);
		System.out.println(Arrays.toString(a));
	}
}