■ 集合类
集合框架中的接口
Collection:集合层次中的根接口,JDK没有提供这个接口直接的实现类。
Set:不能包含重复的元素。SortedSet是一个按照升序排列元素的Set。
List:是一个有序的集合,可以包含重复的元素。提供了按索引访问的方式。
Map:包含了key-value对。Map不能包含重复的key。SortedMap是一个按照升序排列key的Map。
■ ArrayList类
ArrayList:我们可以将其看作是能够自动增长容量的数组。
实例如下:
class ArrayListTest ... {
public static void main(String[] args)...{
ArrayList al=new ArrayList();
al.add("gdfgsd");
al.add("fffffffffffff");
al.add("kkkkkk");
for(int i=0;i<al.size();i++)...{
System.out.println(al.get(i));
}
}
}
编译运行:
虽然编译提示:
“注意: ArrayListTest.java 使用了未经检查或不安全的操作。
注意: 要了解详细信息,请使用 -Xlint:unchecked 重新编译。”
但是,我们仍然可以正常运行出结果,这个原因是由于jdk1.5的泛型警告,我使用的是jdk1.5,如果我们不想出现这样的警告,可以这样:
class ArrayListTest ... {
public static void main(String[] args)...{
ArrayList<String> al=new ArrayList<String>();
al.add("gdfgsd");
al.add("fffffffffffff");
al.add("kkkkkk");
for(int i=0;i<al.size();i++)...{
System.out.println(al.get(i));
}
}
}
编译运行:
使用ArrayList<String>可以解决,具体参考jdk1.5帮助文档,以后我们暂时按照不用管这个警告来运行。
如果我们把System.out.println(al.get(i));替换为:
System.out.println(al);
则编译运行:
我们定义一个Point类,输出Point类的三个对象,程序如下:
class ArrayListTest ... {
public static void main(String[] args)...{
ArrayList al=new ArrayList();
al.add(new Point(3,3));
al.add(new Point(50,50));
al.add(new Point(111,222));
for(int i=0;i<al.size();i++)...{
System.out.println(al.get(i));
}
System.out.println(al);
}
}
class Point ... {
int x,y;
Point(int x,int y)...{
this.x=x;
this.y=y;
}
public String toString()...{
return "x="+x+","+"y="+y;
}
}
编译运行:
也可以利用ArrayList的toArray()返回一个数组:
class ArrayListTest ... {
public static void main(String[] args)...{
ArrayList al=new ArrayList();
al.add(new Point(3,3));
al.add(new Point(50,50));
al.add(new Point(111,222));
for(int i=0;i<al.size();i++)...{
System.out.println(al.get(i));
}
System.out.println(al);
Object[] objs=al.toArray(); //定义一个Object类的数组对象,并通过al返回一个数组
for(int i=0;i<objs.length;i++)...{ //打印出数组对象objs中的元素
System.out.println(objs[i]);
}
}
}
class Point ... {
int x,y;
Point(int x,int y)...{
this.x=x;
this.y=y;
}
public String toString()...{
return "x="+x+","+"y="+y;
}
}
编译运行:
我们也可以利用Arrays.asList()返回一个列表:
class ArrayListTest ... {
public static void main(String[] args)...{
ArrayList al=new ArrayList();
al.add(new Point(3,3));
al.add(new Point(50,50));
al.add(new Point(111,222));
for(int i=0;i<al.size();i++)...{
System.out.println(al.get(i));
}
System.out.println(al);
Object[] objs=al.toArray();
for(int i=0;i<objs.length;i++)...{
System.out.println(objs[i]);
}
List l=Arrays.asList(objs); //定义一个List接口类对象,通过Arrays.asList(objs)获取列表
System.out.println(l);
}
}
class Point ... {
int x,y;
Point(int x,int y)...{
this.x=x;
this.y=y;
}
public String toString()...{
return "x="+x+","+"y="+y;
}
}
编译运行:
返回的时一个固定大小的列表,如果我们改变它就会发生异常,可以用下面的语句测试:
l.add("skyskysky");
编译通过,但是运行出错:
但是,我们可以修改l列表中元素,通过下面语句修改并测试:
l.set( 1 , " 55555555 " );
l.set( 2 , " 99999999 " );
for ( int i = 0 ;i < objs.length;i ++ ) ... {
System.out.println(objs[i]);
}
编译运行:
■ 迭代器(Iterator)
迭代器(Iterator) 给我们提供了一种通用的方式来访问集合中的元素。
Iterator类有三个成员方法:
hasNext() 判断是否有更多的元素
next() 返回下一个元素
remove() 从基于集合删除元素,迭代器返回最后一个元素,它是在实现Iterator接口时可以选择实现的方法
用迭代器实现的实例:
class ArrayListTest ... {
public static void main(String[] args)...{
ArrayList al=new ArrayList();
al.add(new Point(3,3));
al.add(new Point(50,50));
al.add(new Point(111,222));
Iterator it=al.iterator(); //定义一个迭代器,通过iterator方法获得数组对象元素
while(it.hasNext())...{ //判断是否有更多的元素
System.out.println(it.next()); //打印返回的下一个元素
}
}
}
class Point ... {
int x,y;
Point(int x,int y)...{
this.x=x;
this.y=y;
}
public String toString()...{
return "x="+x+","+"y="+y;
}
}
编译运行:
使用remove可选的方法:
class ArrayListTest ... {
public static void main(String[] args)...{
ArrayList al=new ArrayList();
al.add(new Point(3,3));
al.add(new Point(50,50));
al.add(new Point(111,222));
Iterator it=al.iterator();
it.next();
it.remove(); //使用remove方法
while(it.hasNext())...{
System.out.println(it.next());
}
}
}
class Point ... {
int x,y;
Point(int x,int y)...{
this.x=x;
this.y=y;
}
public String toString()...{
return "x="+x+","+"y="+y;
}
}
编译运行:
通过运行结果可见,返回的第一个元素被删除了。
如果我们把next();语句去掉,这样会出现异常,因为remove方法删除的是返回的下一个元素,因为开始还没有返回,所以出错:
如果我们把al环换成l就会出现异常,因为List不支持remove方法,remove方法是可选的。
我们可以实现一个方法,通过传递Connection类的参数,实现迭代器的功能:
class ArrayListTest ... {
public static void printElements(Collection c)...{ //实现一个方法printElements
Iterator it=c.iterator();
while(it.hasNext())...{
System.out.println(it.next());
}
}
public static void main(String[] args)...{
ArrayList al=new ArrayList();
al.add(new Point(3,3));
al.add(new Point(50,50));
al.add(new Point(111,222));
printElements(al); //调用方法printElements
}
}
class Point ... {
int x,y;
Point(int x,int y)...{
this.x=x;
this.y=y;
}
public String toString()...{
return "x="+x+","+"y="+y;
}
}
编译运行:
这样在一个方法中使用迭代器,它的优点就是:不需要针对某一种特定的集合类来编写打印的实现过程,只需要在调用该方法时传递一个集合类的实参就能够完成。
■ Collections类
(1)自然排寻(natural ordering );
能够实现对列表的排序:Collections.sort(),实现如下:
class ArrayListTest ... {
public static void printElements(Collection c)...{
Iterator it=c.iterator();
while(it.hasNext())...{
System.out.println(it.next());
}
}
public static void main(String[] args)...{
ArrayList al=new ArrayList();
Student stu1=new Student(2,"sky2098");
Student stu2=new Student(3,"sky3000");
Student stu3=new Student(1,"sky1999");
al.add(stu1);
al.add(stu2);
al.add(stu3);
Collections.sort(al); //实现排序
printElements(al);
}
}
class Student implements Comparable ... { //必须实现Comparable接口
int num;
String name;
Student(int num,String name)...{
this.num=num;
this.name=name;
}
public int compareTo(Object obj)...{ //实现compareTo方法
Student stu=(Student)obj;
return num>stu.num ? 1 : (num==stu.num ? 0 :-1);
}
public String toString()...{
return "num="+num+","+"name="+name;
}
}
编译运行:
(2)实现比较器(Comparator)接口。
Comparator是java.util包中的接口类。
我们可以定义一个内部类,在内部类中实现比较器。这样比在类的外部定义类实现要合理得多:
class ArrayListTest ... {
public static void printElements(Collection c)...{
Iterator it=c.iterator();
while(it.hasNext())...{
System.out.println(it.next());
}
}
public static void main(String[] args)...{
ArrayList al=new ArrayList();
Student stu1=new Student(2,"vvsky2098"); //我们假设学号可以重复
Student stu2=new Student(3,"kksky3000");
Student stu3=new Student(1,"xxsky1999");
Student stu4=new Student(2,"eesky1999");
al.add(stu1);
al.add(stu2);
al.add(stu3);
al.add(stu4);
Collections.sort(al,new Student.StudentComparator());
printElements(al);
}
}
class Student implements Comparable ... {
int num;
String name;
static class StudentComparator implements Comparator...{ //为方便调用,我们定义了一个静态类
public int compare(Object obj1,Object obj2)...{
Student stu1=(Student)obj1;
Student stu2=(Student)obj2;
return stu1.num>stu2.num?1:(stu1.num==stu2.num?0:-1);
}
}
Student(int num,String name)...{
this.num=num;
this.name=name;
}
public int compareTo(Object obj)...{
Student stu=(Student)obj;
return num>stu.num ? 1 : (num==stu.num ? 0 :-1);
}
public String toString()...{
return "num="+num+","+"name="+name;
}
}
编译运行:
从上面的程序中,做如下说明:
1。StudentComparator类实现了Comparator接口,而接口Comparator有两个成员方法compare和equals,我们只实现了一个compare方法,编译却没有出错,这是为什么呢?
这是因为:所有的类都从Object类直接或者间接派生而来,而Object类中已经有一个equals方法了,所以StudentComparator类已经继承了这个equals方法。
2。sort(List list)
功能描述:自然排序,对指定里表list进行升序排序。
3。sort(List list, Comparator c)
功能描述:根据比较器指定的命令对列表list进行排序。
4。Comparator接口的方法compare(Object obj1,Object obj2)的功能是实现对obj1和obj2进行比较。
另外,我们在对Student类的num比较的同时,希望也对名字按照字母表顺序进行排序,则只需要修改比较器为:
public int compare(Object obj1,Object obj2)...{
Student stu1=(Student)obj1;
Student stu2=(Student)obj2;
int result=stu1.num>stu2.num?1:(stu1.num==stu2.num?0:-1); //对num进行比较
if(result==0)...{ //如果num相同
result=stu1.name.compareTo(stu2.name); //则对名字进行比较
}
return result;
}
}
编译运行:
可见,不仅对num进行排序,也对名字进行了排序。
Collections类还提供了两个个反序排列的方法:
static Comparator reverseOrder()
static Comparator reverseOrder(Comparator cmp)
功能描述:都返回一个比较器对象。
只要把上面程序中
Collections.sort(al,new Student.StudentComparator());
替换为:
Collections.sort(al,Collections.reverseOrder());
就可以实现反序排列。
编译运行:
Arrays类也提供了一个sort方法,在对对象数组进行排序时也可以指定一个比较器对象。
Collectios还提供了下面方法:
取最大和最小的元素:Collections.max()、Collections.min(),比如,我们实现下面的语句:
Student smin = (Student)Collections.min(al);
System.out.println( " smax:[ " + smax + " ], " + " smin:[ " + smin + " ] " );
编译运行:
■ LinkedList类(链表类)
用链表实现栈:
class MyStack ... {
private LinkedList ll=new LinkedList();
public void push(Object obj)...{ //向链表ll中添加元素
ll.addFirst(obj);
}
public Object pop()...{ //向链表ll中删除元素
return ll.removeFirst();
}
public Object peek()...{ //查看链表ll中元素
return ll.getFirst();
}
public boolean empty()...{ //判断链表ll是否为空
return ll.isEmpty();
}
public static void main(String[] args)...{
MyStack ms=new MyStack();
ms.push("aaa");
ms.push("bbb");
ms.push("ccc");
System.out.println(ms.pop());
System.out.println(ms.peek());
System.out.println(ms.pop());
System.out.println(ms.empty());
}
}
编译运行:
用链表实现队列:
class MyQueue ... {
private LinkedList ll=new LinkedList();
public void enQueue(Object obj)...{
ll.addLast(obj);
}
public Object deQueue()...{
return ll.removeFirst();
}
public boolean empty()...{
return ll.isEmpty();
}
public static void main(String[] args)...{
MyQueue mq=new MyQueue();
mq.enQueue("aaa");
mq.enQueue("bbb");
mq.enQueue("ccc");
System.out.println(mq.deQueue());
System.out.println(mq.deQueue());
System.out.println(mq.deQueue());
System.out.println(mq.empty());
}
}
编译运行:
说明:
LinkedList类有很多方法,可以查看帮助文档学习下面这些成员方法:
void add( int index, E element)
boolean addAll(Collection c)
boolean addAll( int index, Collection c)
void addFirst(E o)
void addLast(E o)
void clear()
Object clone()
boolean contains(Object o)
E element()
E get( int index)
E getFirst()
E getLast()
int indexOf(Object o)
int lastIndexOf(Object o)
ListIterator < E > listIterator( int index)
boolean offer(E o)
E peek()
E poll()
E remove()
E remove( int index)
boolean remove(Object o)
E removeFirst()
E removeLast()
E set( int index, E element)
int size()
Object[] toArray()
< T > T[] toArray(T[] a)
利用链表可以实现很多功能。
ArrayList和LinkedList的比较
ArrayList底层采用数组完成,而LinkedList则是以一般的双向链表(double-linked list)完成,其内每个对象除了数据本身外,还有两个 引用,分别指向前一个元素和后一个元素。
如果我们经常在List的开始处增加元素,或者在List中进行插入和删除操作,我们应该使用LinkedList,否则的话,使用ArrayList将更加快速。
■ HashSet类
实现Set接口的hash table(哈希表),依靠HashMap来实现的。
我们应该为要存放到散列表的各个对象定义hashCode()和equals()。
HashSet类实现了Set接口,不能有重复元素。
HashSet类获得表中元素需要通过迭代器完成:
class HashSetTest ... {
public static void main(String[] args)...{
HashSet hs=new HashSet();
hs.add("aaa");
hs.add("bbb");
hs.add("ccc");
hs.add("aaa");
Iterator it=hs.iterator();
while(it.hasNext())...{
System.out.println(it.next());
}
}
}
编译运行:
我们再定义一个Student类:
class HashSetTest ... {
public static void main(String[] args)...{
HashSet hs=new HashSet();
hs.add(new Student(1,"ZhangSan"));
hs.add(new Student(2,"LiSi"));
hs.add(new Student(3,"WangWu"));
hs.add(new Student(1,"ZhangSan"));
Iterator it=hs.iterator();
while(it.hasNext())...{
System.out.println(it.next());
}
}
}
class Student ... {
int num;
String name;
Student(int num,String name)...{
this.num=num;
this.name=name;
}
public String toString()...{
return "num="+num+","+"name="+name;
}
}
编译运行:
可见运行结果并不是按照我们添加对象的顺序打印出来,这是因为:
哈希表是根据对象的散列码计算在内存中的存储位置,而我们实例化一个对象的时候,这个对象在内存中就分配了一个地址,所以,一般来说它们的散列码不同。
我们可以通过重写hashCode方法来改变实例化的对象在内存中的存储地址,这个方法是HashSet类实现Set接口继承而来的:
class HashSetTest ... {
public static void main(String[] args)...{
HashSet hs=new HashSet();
hs.add(new Student(1,"ZhangSan"));
hs.add(new Student(2,"LiSi"));
hs.add(new Student(3,"WangWu"));
hs.add(new Student(1,"ZhangSan"));
Iterator it=hs.iterator();
while(it.hasNext())...{
System.out.println(it.next());
}
}
}
class Student ... {
int num;
String name;
Student(int num,String name)...{
this.num=num;
this.name=name;
}
public int hashCode()...{ //重写了hasCode()函数
return num*name.hashCode();
}
public String toString()...{
return "num="+num+","+"name="+name;
}
}
编译运行:
我们看到,运行结果又发生了变化,这主要体现在hashCode方法的实现上。
如果我们不想打印出相同的对象,必须再实现equals方法:
class HashSetTest ... {
public static void main(String[] args)...{
HashSet hs=new HashSet();
hs.add(new Student(1,"ZhangSan"));
hs.add(new Student(2,"LiSi"));
hs.add(new Student(3,"WangWu"));
hs.add(new Student(1,"ZhangSan"));
Iterator it=hs.iterator();
while(it.hasNext())...{
System.out.println(it.next());
}
}
}
class Student ... {
int num;
String name;
Student(int num,String name)...{
this.num=num;
this.name=name;
}
public int hashCode()...{
return num*name.hashCode();
}
public boolean equals(Object obj)...{ //实现了equals()方法
Student stu=(Student)obj;
return num==stu.num&&name.equals(stu.name);
}
public String toString()...{
return "num="+num+","+"name="+name;
}
}
编译运行:
■ TreeSet类
TreeSet类是java.util包中的类。
TreeSet是依靠TreeMap来实现的。
TreeSet是一个有序集合,TreeSet中元素将按照升序排列,缺省是按照自然顺序进行排列,意味着TreeSet中元素要实现Comparable接口。
我们可以在构造TreeSet对象时,传递实现了Comparator接口的比较器对象:
class TreeSetTest ... {
public static void main(String[] args)...{
TreeSet ts=new TreeSet();
ts.add("bbb");
ts.add("ccc");
ts.add("aaa");
ts.add("bbb");
Iterator it=ts.iterator();
while(it.hasNext())...{
System.out.println(it.next());
}
}
}
编译运行:
可见,再打印输出时自动进行了排序。
当我们也类似地定义一个类的时候,它必须实现Comparable接口。
定义了Studnet类,同时实现了比较器:
class TreeSetTest ... {
public static void main(String[] args)...{
TreeSet ts=new TreeSet();
ts.add("bbb");
ts.add("ccc");
ts.add("aaa");
ts.add("bbb");
Iterator it=ts.iterator();
while(it.hasNext())...{
System.out.println(it.next());
}
}
}
*/
import java.util. * ;
class TreeSetTest ... {
public static void main(String[] args)...{
TreeSet ts=new TreeSet();
ts.add(new Student(1,"ZhangSan"));
ts.add(new Student(2,"LiSi"));
ts.add(new Student(3,"WangWu"));
ts.add(new Student(1,"ZhangSan"));
Iterator it=ts.iterator();
while(it.hasNext())...{
System.out.println(it.next());
}
}
}
class Student implements Comparable ... {
int num;
String name;
static class StudentComparator implements Comparator...{
public int compare(Object obj1,Object obj2)...{
Student stu1=(Student)obj1;
Student stu2=(Student)obj2;
int result=stu1.num>stu2.num?1:(stu1.num==stu2.num?0:-1);
if(result==0)...{
result=stu1.name.compareTo(stu2.name);
}
return result;
}
}
Student(int num,String name)...{
this.num=num;
this.name=name;
}
public int compareTo(Object obj)...{
Student stu=(Student)obj;
return num>stu.num ? 1 : (num==stu.num ? 0 :-1);
}
public String toString()...{
return "num="+num+","+"name="+name;
}
}
编译运行:
由于TreeSet类的构造函数TreeSet(Comparator c) 可以传递一个构造器对象,因此,我们可以在TreeSetTest类的main方法中实例化TreeSet时直接传递一个构造器对象:
TreeSet ts=new TreeSet(new Student.StudentComparator());
编译运行:
这时,打印出的元素不仅按照num排好序,而且也按照name排好序。
如果我们添加了重复的元素,比如:
class TreeSetTest ... {
public static void main(String[] args)...{
//TreeSet ts=new TreeSet();
TreeSet ts=new TreeSet(new Student.StudentComparator());
ts.add(new Student(1,"ZhangSan")); //下面添加了很多重复的元素
ts.add(new Student(2,"LiSi"));
ts.add(new Student(3,"WangWu"));
ts.add(new Student(1,"ZhangSan"));
ts.add(new Student(1,"ZhangSan"));
ts.add(new Student(2,"LiSi"));
ts.add(new Student(3,"WangWu"));
ts.add(new Student(1,"ZhangSan"));
Iterator it=ts.iterator();
while(it.hasNext())...{
System.out.println(it.next());
}
}
}
class Student implements Comparable ... {
int num;
String name;
static class StudentComparator implements Comparator...{
public int compare(Object obj1,Object obj2)...{
Student stu1=(Student)obj1;
Student stu2=(Student)obj2;
int result=stu1.num>stu2.num?1:(stu1.num==stu2.num?0:-1);
if(result==0)...{
result=stu1.name.compareTo(stu2.name);
}
return result;
}
}
Student(int num,String name)...{
this.num=num;
this.name=name;
}
public int compareTo(Object obj)...{
Student stu=(Student)obj;
return num>stu.num ? 1 : (num==stu.num ? 0 :-1);
}
public String toString()...{
return "num="+num+","+"name="+name;
}
}
编译运行:
从上面可见,不会打印出重复的元素。
HashSet和TreeSet的比较
HashSet是基于Hash算法实现的,其性能通常都优于TreeSet。我们通常都应该使用HashSet,在我们需要排序的功能时,我们才使用TreeSet。
■ HashMap类
HashMap对key进行散列:
class HashMapTest ... {
public static void main(String[] args)...{
HashMap hm=new HashMap();
hm.put("one","ZhangSan");
hm.put("two","LiSi");
hm.put("three","WangWu");
System.out.println(hm.get("one"));
System.out.println(hm.get("two"));
System.out.println(hm.get("three"));
}
}
编译运行:
HashMap类的成员方法:
V get(Object key)
Set < K > keySet() // 获取键的视图
Collection < V > values()
Set < Map.Entry < K,V >> entrySet()
我们看一下后面三个方法:
在使用keySet() 时需要用迭代实现:
class HashMapTest ... {
public static void printElements(Collection coll)...{
Iterator it=coll.iterator();
while(it.hasNext())...{
System.out.println(it.next());
}
}
public static void main(String[] args)...{
HashMap hm=new HashMap();
hm.put("one","ZhangSan");
hm.put("two","LiSi");
hm.put("three","WangWu");
Set keys=hm.keySet();
System.out.println("keys:");
printElements(keys); //打印出键名
Collection values=hm.values();
printElements(values); //打印出键值
Set entry=hm.entrySet();
System.out.println(entry); //直接打印出键名和键值
printElements(values); //这个语句也一样能打印出键名和键值
}
}
编译运行:
我们也可以使用Map类的一个静态静态接口Map.Entry来实现打印出键名和键值:
class HashMapTest ... {
public static void main(String[] args)...{
HashMap hm=new HashMap();
hm.put("one","ZhangSan");
hm.put("two","LiSi");
hm.put("three","WangWu");
Set entry=hm.entrySet();
System.out.println(entry);
Iterator it=entry.iterator(); //构造迭代器
while(it.hasNext())...{
Map.Entry me=(Map.Entry)it.next();
System.out.println(me.getKey()+"="+me.getValue());
}
}
}
编译运行:
Map类的一个静态静态接口为:
static interface Map.Entry<K,V>
这个接口的方法有:
K getKey()
V getValue()
int hashCode()
V setValue(V value)
其中,我们在上面程序中使用到了获取键名getKey()与获取键值getValue()两个方法。
■ TreeMap类
TreeMap按照key进行排序。
用法和HashMap类类似。
HashMap和TreeMap的比较
和Set类似,HashMap的速度通常都比TreeMap快,只有在需要排序的功能的时候,才使用TreeMap。
■ Java1.0/1.1的集合类
Vector:用ArrayList代替Vector,因为获得一个同步的List时ArrayList要比Vector稍微慢一些,但是Vector有一些legacy operations,使用起来要特别小心。
Hashtable:用HashMap代替Hashtable,因为获得一个同步的Map时HashMap要比Hashtable稍微慢一些,但是Hashtable有一些legacy operations,使用起来要特别小心。
Collections类中有三个同步的方法:
synchronizedCollection(Collection < T > c)
Returns a synchronized (thread - safe) collection backed by the specified collection.
static < T > List < T >
synchronizedList(List < T > list)
Returns a synchronized (thread - safe) list backed by the specified list.
static < K,V > Map < K,V >
synchronizedMap(Map < K,V > m)
Returns a synchronized (thread - safe) map backed by the specified map.
static < T > Set < T >
synchronizedSet(Set < T > s)
Returns a synchronized (thread - safe) set backed by the specified set.
它们分别返回一个collection,list,map,set类型对象。
Satck:用LinkedList代替Stack。
Stack类继承自java.util.Vector类,这使得它继承了java.util.Vector类的elementAt方法,可以通过索引访问栈美元素。然而对于栈来说,它是后进先出的,只能根据栈的结构特点来访问元素,这是Stack类设计时的缺陷。所以,我们尽量不用Stack类,而用LinkedList类来实现栈。
Properties类
Properties类继承自java.util.Hashtable,使用它也可以来对键进行操作。Properties类可以被保存在一个流中,也可以从流中加载,主要用来存储字符串类型的键值对。
System类中有一个static Properties getProperties() 方法,我们可以通过Properties类的 void list(PrintStream out)方法传递一个PrintStream类的对象,并打印出来:
class PropertyTest ... {
public static void main(String[] args)...{
Properties pps=System.getProperties();
pps.list(System.out);
}
}
编译运行:
通过加载ini文件,读取配置信,获取键值对,我们首先要在建立的WinSun.ini文件中输入键值对:
company=Winsun
CEO=ZhangSan
保存后,通过下面程序读取:
import java.io. * ;
class PropertyTest ... {
public static void main(String[] args)...{
Properties pps=new Properties(); //实例化一个Properties类的对象
try...{
pps.load(new FileInputStream("Winsun.ini")); //因为load方法会抛出异常,所以要进行捕捉处理
Enumeration enume=pps.propertyNames(); //定义一个枚举类的对象,生成枚举器
while(enume.hasMoreElements())...{
String strKey=(String)enume.nextElement();
String strValues=pps.getProperty(strKey);
System.out.println(strKey+"="+strValues);
}
}catch(Exception e)...{
e.printStackTrace();
}
}
}
编译运行:
读取成功。
我们可以用迭代器(Iterator)获取集合中元素,而枚举器(Enumeration)一般不用,除非必要。
Enumeration类的成员方法和Iterator很类似:
boolean hasMoreElements()
E nextElement()
Properties类的对象中保存的都是String类型的值。
程序中使用到的方法:
void load(InputStream inStream)
String getProperty(String key)
Properties类的propertyNames方法返回一个Enumeration类型的对象:
Enumeration<?> propertyNames()
可以通过枚举器得到元素的值。
■