java程序设计--孙鑫java无难事Lesson8《集合类》
1.集合框架中的接口
本节要点:
集合类的操作和特性(
数据结构相关知识可参见《数据结构》教材,这部分知识,理论比较丰富, 在此略去 )
详细内容:
详细内容:
Collection:集合层次中的根接口,JDK没有提供这个接口直接的实现类。
Set:不能包含重复的元素。SortedSet是一个按照升序排列元素的Set。
List:是一个有序的集合,可以包含重复的元素。提供了按索引访问的方式。
Map:包含了key-value对。Map不能包含重复的key。
SortedMap是一个按照升序排列key的Map。
集合类框架中的接口如下图所示:![](http://hi.csdn.net/attachment/201203/16/0_1331884676NwEF.gif)
2.集合框架中的实现类
集合框架中的实现类整齐层次如下图所示:
ArrayList:
我们可以将ArrayList看作是能够自动增长容量的数组。
利用ArrayList的toArray()返回一个数组。
Arrays.asList()返回一个列表。
迭代器(Iterator) 给我们提供了一种通用的方式来访问集合中的元素。
LinkedList:
LinkedList是采用双向循环链表实现的。
利用LinkedList实现栈(stack)、队列(queue)、双向队列(double-ended queue )。
基于LinkedList的栈测试代码如下:
- //基于LinkedList的栈测试
- import java.util.* ;
- class MyStack
- {
- private LinkedList ll=new LinkedList();
- public void push(Object o)
- {
- ll.addFirst(o);
- }
- public Object pop()
- {
- return ll.removeFirst();
- }
- public Object peek()
- {
- return ll.peekFirst();
- }
- public boolean empty()
- {
- return ll.isEmpty();
- }
- public static void main(String[] args)
- { MyStack ms=new MyStack();
- ms.push("one");
- ms.push("two");
- ms.push("three");
- System.out.println(ms.pop());
- System.out.println(ms.peek());
- System.out.println(ms.pop());
- System.out.println(ms.empty());
- //运行结果
- /*
- three
- two
- two
- false */
- }
- }
//基于LinkedList的栈测试
import java.util.* ;
class MyStack
{
private LinkedList ll=new LinkedList();
public void push(Object o)
{
ll.addFirst(o);
}
public Object pop()
{
return ll.removeFirst();
}
public Object peek()
{
return ll.peekFirst();
}
public boolean empty()
{
return ll.isEmpty();
}
public static void main(String[] args)
{ MyStack ms=new MyStack();
ms.push("one");
ms.push("two");
ms.push("three");
System.out.println(ms.pop());
System.out.println(ms.peek());
System.out.println(ms.pop());
System.out.println(ms.empty());
//运行结果
/*
three
two
two
false */
}
}
基于LinkedList的队列测试代码如下:
- //基于LinkedList的队列测试
- import java.util.*;
- class MyQueue
- {
- private LinkedList ll=new LinkedList();
- public void put(Object o)
- {
- ll.add(o);
- }
- public Object get()
- {
- return ll.removeFirst() ;
- }
- public boolean empty()
- {
- return ll.isEmpty();
- }
- public static void main(String[] args)
- {
- MyQueue mq=new MyQueue();
- mq.put("one");
- mq.put("two");
- mq.put("three");
- System.out.println(mq.get());
- System.out.println(mq.get());
- System.out.println(mq.get());
- System.out.println(mq.empty());
- //运行结果
- /*
- one
- two
- three
- true */
- }
- }
//基于LinkedList的队列测试
import java.util.*;
class MyQueue
{
private LinkedList ll=new LinkedList();
public void put(Object o)
{
ll.add(o);
}
public Object get()
{
return ll.removeFirst() ;
}
public boolean empty()
{
return ll.isEmpty();
}
public static void main(String[] args)
{
MyQueue mq=new MyQueue();
mq.put("one");
mq.put("two");
mq.put("three");
System.out.println(mq.get());
System.out.println(mq.get());
System.out.println(mq.get());
System.out.println(mq.empty());
//运行结果
/*
one
two
three
true */
}
}
(2)Collections类排序:Collections.sort()
(1)自然排寻(natural ordering );(2)实现比较器(Comparator)接口。
取最大和最小的元素:Collections.max()、Collections.min()。
在已排序的List中搜索指定的元素:Collectons.binarySearch()。
自然排序、实现比较器接口、迭代器使用的测试代码如下:
- import java.util.*;
- class ArrayListTest
- {
- //迭代输出元素
- public static void PrintElements(Collection e)
- {
- Iterator iter=e.iterator();
- while(iter.hasNext())
- {
- System.out.println(iter.next());
- }
- }
- public static void main(String[] args)
- {
- /*
- //基本测试
- ArrayList al=new ArrayList();
- al.add("java");
- al.add("ArrayList");
- al.add("Test");
- for(int i=0;i<al.size();i++)
- System.out.println(al.get(i));
- System.out.println(al);//[java, ArrayList, Test] 调用ArrayList的toString方法
- */
- /*
- //Collection.toArray和Arrays.asList转换测试
- ArrayList al=new ArrayList();
- al.add("java");
- al.add("ArrayList");
- al.add("Test");
- Object[] objs=al.toArray();//列表转换为数组
- for(int i=0;i<objs.length;i++)
- System.out.println(objs[i]);
- List ls=Arrays.asList(objs);//数组转换为列表 asList返回一个固定大小(a fixed-size)的列表
- PrintElements(ls);
- //ls.add("Add");//error .UnsupportedOperationException 因为固定大小
- */
- /*
- //迭代器使测试1
- ArrayList al=new ArrayList();
- al.add("java");
- al.add("ArrayList");
- al.add("Test");
- Object[] objs=al.toArray();
- List ls=Arrays.asList(objs);//asList返回一个固定大小(a fixed-size)的列表
- //Iterator iter=al.iterator();//ArrayList的迭代器
- Iterator iter=ls.iterator();//List的迭代器 不支持remove方法 因为固定大小
- iter.next();
- //iter.remove();//删除之前必须由next返回一个元素
- while(iter.hasNext())
- {
- System.out.println(iter.next());
- }
- */
- /*
- //迭代器测试2
- List ls=new ArrayList();
- ls.add("java");
- ls.add("ArrayList");
- ls.add("Test");
- Iterator iter=ls.iterator();//List的迭代器 此时支持remove方法 因为没有固定大小
- iter.next();
- iter.remove();
- while(iter.hasNext())
- {
- System.out.println(iter.next());
- }
- */
- /*
- //排序测试代码
- Student stu1=new Student(3,"ZhangSan");
- Student stu2=new Student(1,"LiSi");
- Student stu3=new Student(2,"ZhaoEr");
- Student stu4=new Student(2,"WangWu");
- ArrayList al=new ArrayList();
- al.add(stu1);
- al.add(stu2);
- al.add(stu3);
- al.add(stu4);
- */
- //Collections.sort(al);//按自然顺序升序排列 必须实现Comparable接口
- //自然排序运行结果
- /*
- num=1 name=LiSi
- num=2 name=ZhaoEr
- num=2 name=WangWu
- num=3 name=ZhangSan
- */
- //Collections.sort(al,new Student.StudentComparator());//按指定Comparator的排序 必须实现Comparator接口
- //指定comparator排序结果
- /*
- num=1 name=LiSi
- num=2 name=WangWu
- num=2 name=ZhaoEr
- num=3 name=ZhangSan
- */
- //Collections.sort(al,Collections.reverseOrder());//反序排序 reverseOrder方法返回一个comparator
- //逆序排序结果
- /*
- num=3 name=ZhangSan
- num=2 name=ZhaoEr
- num=2 name=WangWu
- num=1 name=LiSi
- */
- //PrintElements(al);//迭代输出元素
- }
- }
- class Student implements Comparable
- {
- int num;
- String name;
- //利用内部类实现Comparator接口
- static class StudentComparator implements Comparator
- {
- public int compare(Object o1,Object o2)
- {
- Student stu1=(Student)o1;
- Student stu2=(Student)o2;
- int ret=stu1.num>stu2.num?1:(stu1.num==stu2.num?0:-1);
- if(ret==0)
- ret=stu1.name.compareTo(stu2.name);
- return ret;
- }
- //注意:equals方法从Object类继承而来 因此可以不用实现equals方法
- }
- Student(int num,String name)
- {
- this.num=num;
- this.name=name;
- }
- //实现Comparable接口
- public int compareTo(Object o)
- {
- Student stu=(Student)o;
- return this.num>stu.num?1:(this.num==stu.num?0:-1);
- }
- public String toString()
- {
- return "num="+num+" "+"name="+name;
- }
- }
import java.util.*;
class ArrayListTest
{
//迭代输出元素
public static void PrintElements(Collection e)
{
Iterator iter=e.iterator();
while(iter.hasNext())
{
System.out.println(iter.next());
}
}
public static void main(String[] args)
{
/*
//基本测试
ArrayList al=new ArrayList();
al.add("java");
al.add("ArrayList");
al.add("Test");
for(int i=0;i<al.size();i++)
System.out.println(al.get(i));
System.out.println(al);//[java, ArrayList, Test] 调用ArrayList的toString方法
*/
/*
//Collection.toArray和Arrays.asList转换测试
ArrayList al=new ArrayList();
al.add("java");
al.add("ArrayList");
al.add("Test");
Object[] objs=al.toArray();//列表转换为数组
for(int i=0;i<objs.length;i++)
System.out.println(objs[i]);
List ls=Arrays.asList(objs);//数组转换为列表 asList返回一个固定大小(a fixed-size)的列表
PrintElements(ls);
//ls.add("Add");//error .UnsupportedOperationException 因为固定大小
*/
/*
//迭代器使测试1
ArrayList al=new ArrayList();
al.add("java");
al.add("ArrayList");
al.add("Test");
Object[] objs=al.toArray();
List ls=Arrays.asList(objs);//asList返回一个固定大小(a fixed-size)的列表
//Iterator iter=al.iterator();//ArrayList的迭代器
Iterator iter=ls.iterator();//List的迭代器 不支持remove方法 因为固定大小
iter.next();
//iter.remove();//删除之前必须由next返回一个元素
while(iter.hasNext())
{
System.out.println(iter.next());
}
*/
/*
//迭代器测试2
List ls=new ArrayList();
ls.add("java");
ls.add("ArrayList");
ls.add("Test");
Iterator iter=ls.iterator();//List的迭代器 此时支持remove方法 因为没有固定大小
iter.next();
iter.remove();
while(iter.hasNext())
{
System.out.println(iter.next());
}
*/
/*
//排序测试代码
Student stu1=new Student(3,"ZhangSan");
Student stu2=new Student(1,"LiSi");
Student stu3=new Student(2,"ZhaoEr");
Student stu4=new Student(2,"WangWu");
ArrayList al=new ArrayList();
al.add(stu1);
al.add(stu2);
al.add(stu3);
al.add(stu4);
*/
//Collections.sort(al);//按自然顺序升序排列 必须实现Comparable接口
//自然排序运行结果
/*
num=1 name=LiSi
num=2 name=ZhaoEr
num=2 name=WangWu
num=3 name=ZhangSan
*/
//Collections.sort(al,new Student.StudentComparator());//按指定Comparator的排序 必须实现Comparator接口
//指定comparator排序结果
/*
num=1 name=LiSi
num=2 name=WangWu
num=2 name=ZhaoEr
num=3 name=ZhangSan
*/
//Collections.sort(al,Collections.reverseOrder());//反序排序 reverseOrder方法返回一个comparator
//逆序排序结果
/*
num=3 name=ZhangSan
num=2 name=ZhaoEr
num=2 name=WangWu
num=1 name=LiSi
*/
//PrintElements(al);//迭代输出元素
}
}
class Student implements Comparable
{
int num;
String name;
//利用内部类实现Comparator接口
static class StudentComparator implements Comparator
{
public int compare(Object o1,Object o2)
{
Student stu1=(Student)o1;
Student stu2=(Student)o2;
int ret=stu1.num>stu2.num?1:(stu1.num==stu2.num?0:-1);
if(ret==0)
ret=stu1.name.compareTo(stu2.name);
return ret;
}
//注意:equals方法从Object类继承而来 因此可以不用实现equals方法
}
Student(int num,String name)
{
this.num=num;
this.name=name;
}
//实现Comparable接口
public int compareTo(Object o)
{
Student stu=(Student)o;
return this.num>stu.num?1:(this.num==stu.num?0:-1);
}
public String toString()
{
return "num="+num+" "+"name="+name;
}
}
(3)HashSet与HashMap
HashSet:实现Set接口的hash table(哈希表),依靠HashMap来实现的。我们应该为要存放到散列表的各个对象定义hashCode()和equals()。
HashMap:
HashMap对key进行散列。
keySet()、values()、entrySet()。
HashSet和HashMap测试代码如下:
- //HashSet测试代码
- import java.util.* ;
- class HashSetTest
- {
- public static void main(String[] args)
- {
- /*
- //基本测试
- HashSet hs=new HashSet();
- hs.add("one");
- hs.add("two");
- hs.add("three");
- hs.add("four");
- hs.add("one");//不能重复元素 将无法保存重复元素
- Iterator iter=hs.iterator();
- while(iter.hasNext())
- System.out.println(iter.next());
- */
- //哈希码计算的测试 hashCode方法实现
- HashSet hs=new HashSet();
- hs.add(new Student(1,"ZhangSan"));
- hs.add(new Student(2,"LiSi"));
- hs.add(new Student(3,"WangWu"));
- //根据对象的散列码计算 new产生不同对象
- //因此hashset认为是两个不同的对象 存贮了两个对象 虽然是重复的
- hs.add(new Student(1,"ZhangSan"));
- Iterator iter=hs.iterator();
- while(iter.hasNext())
- System.out.println(iter.next());
- //未实现Student类的hasCode和equals方法时 运行结果
- /*
- num=2 name LiSi
- num=1 name ZhangSan
- num=1 name ZhangSan
- num=3 name WangWu
- */
- //实现了Student类的hasCode和equals方法时运行结果
- /*
- num=2 name LiSi
- num=1 name ZhangSan
- num=3 name WangWu
- */
- }
- }
- class Student
- {
- int num;
- String name;
- Student(int num,String name)
- {
- this.num=num;
- this.name=name;
- }
- //需要覆盖hashCode和equals方法
- public int hashCode()
- {
- return num*(name.hashCode());
- }
- public boolean equals(Object o)
- {
- Student stu=(Student)o;
- return this.num==stu.num && this.name.equals(stu.name);
- }
- public String toString()
- {
- return "num="+num+" "+"name"+" "+name;
- }
- }
//HashSet测试代码
import java.util.* ;
class HashSetTest
{
public static void main(String[] args)
{
/*
//基本测试
HashSet hs=new HashSet();
hs.add("one");
hs.add("two");
hs.add("three");
hs.add("four");
hs.add("one");//不能重复元素 将无法保存重复元素
Iterator iter=hs.iterator();
while(iter.hasNext())
System.out.println(iter.next());
*/
//哈希码计算的测试 hashCode方法实现
HashSet hs=new HashSet();
hs.add(new Student(1,"ZhangSan"));
hs.add(new Student(2,"LiSi"));
hs.add(new Student(3,"WangWu"));
//根据对象的散列码计算 new产生不同对象
//因此hashset认为是两个不同的对象 存贮了两个对象 虽然是重复的
hs.add(new Student(1,"ZhangSan"));
Iterator iter=hs.iterator();
while(iter.hasNext())
System.out.println(iter.next());
//未实现Student类的hasCode和equals方法时 运行结果
/*
num=2 name LiSi
num=1 name ZhangSan
num=1 name ZhangSan
num=3 name WangWu
*/
//实现了Student类的hasCode和equals方法时运行结果
/*
num=2 name LiSi
num=1 name ZhangSan
num=3 name WangWu
*/
}
}
class Student
{
int num;
String name;
Student(int num,String name)
{
this.num=num;
this.name=name;
}
//需要覆盖hashCode和equals方法
public int hashCode()
{
return num*(name.hashCode());
}
public boolean equals(Object o)
{
Student stu=(Student)o;
return this.num==stu.num && this.name.equals(stu.name);
}
public String toString()
{
return "num="+num+" "+"name"+" "+name;
}
}
- //HashMap测试代码
- import java.util.* ;
- class HashMapTest
- {
- public static void PrintElements(Collection e)
- {
- Iterator iter=e.iterator();
- while(iter.hasNext())
- {
- System.out.println(iter.next());
- }
- }
- public static void main(String[] args)
- {
- HashMap hm= new HashMap();
- hm.put(1,"ZhangSan");
- hm.put(2,"LiSi");
- hm.put(3,"WangWu");
- //由键获取键值
- System.out.println("values getted from key:");
- System.out.println(hm.get(1));
- System.out.println(hm.get(2));
- System.out.println(hm.get(3));
- //获取键视图
- Set keys=hm.keySet();
- System.out.println("keys view:");
- PrintElements(keys);
- //获取值视图
- Collection values=hm.values();
- System.out.println("values view:");
- PrintElements(values);
- //获取键值对
- Set Entries =hm.entrySet();
- System.out.println("Entries:");
- PrintElements(Entries);
- //迭代Entries
- Iterator iter=Entries.iterator();
- System.out.println("keys and values in Entries:");
- while(iter.hasNext())
- {
- Map.Entry en= (Map.Entry)iter.next();
- System.out.println(en.getKey()+":"+en.getValue());
- }
- /*
- //运行结果
- values getted from key:
- ZhangSan
- LiSi
- WangWu
- keys view:
- 1
- 2
- 3
- values view:
- ZhangSan
- LiSi
- WangWu
- Entries:
- 1=ZhangSan
- 2=LiSi
- 3=WangWu
- keys and values in Entries:
- 1:ZhangSan
- 2:LiSi
- 3:WangWu
- */
- }
- }
//HashMap测试代码
import java.util.* ;
class HashMapTest
{
public static void PrintElements(Collection e)
{
Iterator iter=e.iterator();
while(iter.hasNext())
{
System.out.println(iter.next());
}
}
public static void main(String[] args)
{
HashMap hm= new HashMap();
hm.put(1,"ZhangSan");
hm.put(2,"LiSi");
hm.put(3,"WangWu");
//由键获取键值
System.out.println("values getted from key:");
System.out.println(hm.get(1));
System.out.println(hm.get(2));
System.out.println(hm.get(3));
//获取键视图
Set keys=hm.keySet();
System.out.println("keys view:");
PrintElements(keys);
//获取值视图
Collection values=hm.values();
System.out.println("values view:");
PrintElements(values);
//获取键值对
Set Entries =hm.entrySet();
System.out.println("Entries:");
PrintElements(Entries);
//迭代Entries
Iterator iter=Entries.iterator();
System.out.println("keys and values in Entries:");
while(iter.hasNext())
{
Map.Entry en= (Map.Entry)iter.next();
System.out.println(en.getKey()+":"+en.getValue());
}
/*
//运行结果
values getted from key:
ZhangSan
LiSi
WangWu
keys view:
1
2
3
values view:
ZhangSan
LiSi
WangWu
Entries:
1=ZhangSan
2=LiSi
3=WangWu
keys and values in Entries:
1:ZhangSan
2:LiSi
3:WangWu
*/
}
}
(4)TreeSet与TreeMap
TreeSet:
TreeSet是依靠TreeMap来实现的。
TreeSet是一个有序集合,TreeSet中元素将按照升序排列,缺省是按照自然顺序进行排列,意味着TreeSet中元素要实现Comparable接口。
我们可以在构造TreeSet对象时,传递实现了Comparator接口的比较器对象。
TreeMap:TreeMap按照key进行排序。
TreeSet测试代码如下:
- //TreeSet测试代码
- import java.util.* ;
- class TreeSetTest
- {
- public static void main(String[] args)
- {
- /*
- //基本使用
- TreeSet ts=new TreeSet();
- ts.add("java");
- ts.add("TreeSet");
- ts.add("Test");
- Iterator iter=ts.iterator();
- while(iter.hasNext())
- System.out.println(iter.next());
- */
- //由指定比较器构造TreeSet
- TreeSet ts=new TreeSet(new Student.StudentComparator());
- ts.add(new Student(3,"ZhangSan"));
- ts.add(new Student(1,"LiSi"));
- ts.add(new Student(2,"ZhaoEr"));
- ts.add(new Student(2,"WangWu"));
- Iterator iter=ts.iterator();
- while(iter.hasNext())
- System.out.println(iter.next());
- }
- }
- class Student
- {
- int num;
- String name;
- //实现比较器
- static class StudentComparator implements Comparator
- {
- public int compare(Object o1,Object o2)
- {
- Student stu1=(Student)o1;
- Student stu2=(Student)o2;
- int ret=stu1.num>stu2.num?1:(stu1.num==stu2.num?0:-1);
- if(ret==0)
- ret=stu1.name.compareTo(stu2.name);
- return ret;
- }
- //equals方法从Object类继承而来 因此可以不用实现这个方法
- }
- Student(int num,String name)
- {
- this.num=num;
- this.name=name;
- }
- public String toString()
- {
- return "num="+num+" "+"name="+name;
- }
- }
//TreeSet测试代码
import java.util.* ;
class TreeSetTest
{
public static void main(String[] args)
{
/*
//基本使用
TreeSet ts=new TreeSet();
ts.add("java");
ts.add("TreeSet");
ts.add("Test");
Iterator iter=ts.iterator();
while(iter.hasNext())
System.out.println(iter.next());
*/
//由指定比较器构造TreeSet
TreeSet ts=new TreeSet(new Student.StudentComparator());
ts.add(new Student(3,"ZhangSan"));
ts.add(new Student(1,"LiSi"));
ts.add(new Student(2,"ZhaoEr"));
ts.add(new Student(2,"WangWu"));
Iterator iter=ts.iterator();
while(iter.hasNext())
System.out.println(iter.next());
}
}
class Student
{
int num;
String name;
//实现比较器
static class StudentComparator implements Comparator
{
public int compare(Object o1,Object o2)
{
Student stu1=(Student)o1;
Student stu2=(Student)o2;
int ret=stu1.num>stu2.num?1:(stu1.num==stu2.num?0:-1);
if(ret==0)
ret=stu1.name.compareTo(stu2.name);
return ret;
}
//equals方法从Object类继承而来 因此可以不用实现这个方法
}
Student(int num,String name)
{
this.num=num;
this.name=name;
}
public String toString()
{
return "num="+num+" "+"name="+name;
}
}
(5)几种类的比较ArrayList和LinkedList的比较:
ArrayList底层采用数组完成,而LinkedList则是以一般的双向链表(double-linked list)完成,其内每个对象除了数据本身外,还有两个 引用,分别指向前一个元素和后一个元素。
如果我们经常在List的开始处增加元素,或者在List中进行插入和删除操作,我们应该使用LinkedList,否则的话,使用ArrayList将更加快速。
HashSet和TreeSet的比较:
HashSet是基于Hash算法实现的,其性能通常都优于TreeSet。我们通常都应该使用HashSet,在我们需要排序的功能时,我们才使用TreeSet。
HashMap和TreeMap的比较:
和Set类似,HashMap的速度通常都比TreeMap快,只有在需要排序的功能的时候,才使用TreeMap。
3.properties类
新建一个配置文件如下图所示:
![](http://hi.csdn.net/attachment/201203/16/0_1331884745dRl9.gif)
新建PropTest 测试代码如下:
- //properties类测试代码
- import java.util.*;
- import java.io.*;
- class PropTest
- {
- public static void main(String[] args)
- {
- /*
- //获取当前系统属性
- //Properties prop=System.getProperties();
- //prop.list(System.out);
- */
- //读取ini配置文件信息
- Properties pps=new Properties();
- try
- {
- pps.load(new FileInputStream("Propini.ini"));//从输入流中读取属性列表 列表由键值对组成
- //获取ini文件中键的枚举
- Enumeration er=pps.propertyNames();
- while(er.hasMoreElements())
- {
- String key=(String)er.nextElement();
- System.out.println(key+"="+pps.getProperty(key));
- }
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- }
- }
//properties类测试代码
import java.util.*;
import java.io.*;
class PropTest
{
public static void main(String[] args)
{
/*
//获取当前系统属性
//Properties prop=System.getProperties();
//prop.list(System.out);
*/
//读取ini配置文件信息
Properties pps=new Properties();
try
{
pps.load(new FileInputStream("Propini.ini"));//从输入流中读取属性列表 列表由键值对组成
//获取ini文件中键的枚举
Enumeration er=pps.propertyNames();
while(er.hasMoreElements())
{
String key=(String)er.nextElement();
System.out.println(key+"="+pps.getProperty(key));
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
//运行结果university=HBNU
department=CS
class=0801