Java系列(二十)__Java类集

Java系列(二十)__Java类集

1、Collection集合接口

在之前学习链表的时候可以发现,当使用add()方法向链表增加数据的时候,每次保存的都是一个对象的数据,而Collection操作过程之中每次也只能够保存一个对象。在Collection接口之中一共定义了15个方法,那么常用的方法如下:

No.

方法名称

类型

描述

1

public boolean add(E e)

普通

向集合之中保存数据

2

public void clear()

普通

清空集合

3

public boolean contains(Object o)

普通

查询集合之中是否包含有指定对象,需要equals()

4

public boolean remove(Object o)

普通

删除对象,需要equals()

5

public boolean isEmpty()

普通

判断集合是否为空集合

6

public int size()

普通

取得集合的长度

7

public Object[] toArray()

普通

将集合以对象数组的形式返回

8

public Iterator iterator()

普通

为Iterator接口实例化

         在以上所给出的方法之中,99%的情况下是使用add()、iterator()两个方法,其它的方法都很少使用。但是在开发之中不会去直接使用Collection(时代已经结束了),都会使用Collection下的两个子接口:List(允许重复)、Set(不允许重复)。




2、List集合接口

List接口是Collection之中最为常用的子接口,也是大家在开发过程之中主要使用的接口。但是List子接口针对于Collection子接口做了大量的功能扩充,而主要扩充的方法有如下几个:

No.

方法名称

类型

描述

1

public E get(int index)

普通

取得指定索引位置上的对象

2

public E set(int index, E element)

普通

修改指定索引位置上的对象

3

public ListIterator listIterator()

普通

为ListIterator接口实例化

         那么接口完成后如果要想使用接口那么一定需要子类,而常用的两个子类:ArrayList、Vector。

2.1、新的子类:ArrayList(90%)

         ArrayList是在JDK 1.2之后引入的,或者更加明确的讲像Collection、List等都是JDK 1.2之后引入的,也是在List接口使用过程之中最为常见的一个子类。

范例:使用ArrayList

package cn.mldn.demo;

import java.util.ArrayList;

import java.util.List;

public class TestDemo {

    public static void main(String[] args)throws Exception {

        List all = new ArrayList() ;

        all.add("HELLO") ;

        all.add("HELLO") ;  // 保存了重复数据

        all.add("WORLD") ;

        System.out.println(all);

    }

}

         但是在很多时候可以采用循环的方式输出,因为在List子接口里面扩充了一个get()方法,所以就可以使用for循环。

范例:循环输出List集合

package cn.mldn.demo;

import java.util.ArrayList;

import java.util.List;

public class TestDemo {

    public static void main(String[] args)throws Exception {

        List all = new ArrayList() ;

        all.add("HELLO") ;

        all.add("HELLO") ;  // 保存了重复数据

        all.add("WORLD") ;

        for (int x = 0; x < all.size(); x++) {

            System.out.println(all.get(x));

        }

    }

}

范例:验证其它方法

package cn.mldn.demo;

import java.util.ArrayList;

import java.util.List;

public class TestDemo {

    public static void main(String[] args)throws Exception {

        List all = new ArrayList() ;

        System.out.println(all.isEmpty());

        all.add("HELLO") ;

        all.add("HELLO") ;  // 保存了重复数据

        all.add("WORLD") ;

        System.out.println(all.isEmpty());

        all.set(0, "hello") ;   // 此方法也是List扩充

        all.remove("WORLD") ;

        System.out.println(all);

    }

}

         但是以上的程序之中发现操作的数据类型都是String,那么String类是一个比较完善的类,那么下面使用一个自定义的类进行操作。

范例:保存自定义类对象

package cn.mldn.demo;

import java.util.ArrayList;

import java.util.List;

class Person {

    private String name ;

    private int age ;

    public Person(String name,int age) {

        this.name = name ;

        this.age = age ;

    }

    @Override

    public String toString() {

        return "姓名:" +this.name + ",年龄 :" + this.age + "\n" ;

    }

    @Override

    public boolean equals(Object obj) {

        if (obj ==null) {

           return false ;

        }

        if (this == obj) {

           return true ;

        }

        if (!(objinstanceof Person)) {

           return false ;

        }

        Person per = (Person) obj ;

        if (per.name.equals(this.name) && per.age ==this.age) {

           return true ;

        }

        return false ;

    }

}

public class TestDemo {

    public static void main(String[] args)throws Exception {

        List all = new ArrayList() ;

        all.add(new Person("张三",20)) ;

        all.add(new Person("李四",21)) ;

        all.add(new Person("王五",19)) ;

        all.remove(new Person("王五",19)) ;  // 删除

        System.out.println(all.contains(new Person("李四",21)));

        System.out.println(all);

    }

}

         那么在之前使用的链表操作,在List接口上可以方便的使用,使用的规则与之前完全一样,可是List所采用的程序的逻辑更加合理,性能更好,所以不会使用自定义链表,都会使用List接口操作。

2.2、旧的子类:Vector(10%)

         Vector是从JDK 1.0的时候引入的操作类,最早是用于纯粹的保存多个对象,同时在JDK 1.2之后为了让其可以继续使用,于是让Vector类多实现了一个List接口,所以List接口下有两个常用的子类:ArrayList、Vector。

         既然Vector也是List接口的子类,所以在使用上,不管使用ArrayList还是Vector不会有任何的区别。

范例:验证Vector

package cn.mldn.demo;

import java.util.List;

import java.util.Vector;

public class TestDemo {

    public static void main(String[] args)throws Exception {

        List all = new Vector() ;

        all.add("HELLO") ;

        all.add("HELLO") ;  // 保存了重复数据

        all.add("WORLD") ;

        System.out.println(all);

    }

}

面试题:请解释ArrayList和Vector区别?

No.

区别

ArrayList

Vector

1

推出时间

JDK 1.2时推出

JDK 1.0时推出

2

性能

采用异步处理方式,性能较高

采用同步处理方式,性能较低

3

安全性

数据安全性差

数据安全性高

4

输出

Iterator、ListIterator、foreach

Iterator、ListIterator、foreach、Enumeration

         考虑到日后的开发异步开发居多,所以以ArrayList类为主。




3、Set集合接口

Set之中保存的元素是不能够有重复,但是Set接口并不像List接口那样对Collection进行了方法的扩充,而是完整的继承了Collection接口的所有方法,那么也就意味着,在之前使用的get()方法无法使用了。

         Set子接口之中重要使用两个常用的子类:HashSet、TreeSet。

3.1、散列存放的子类:HashSet(90%)

         Hash是一种散列算法,指的保存数据没有序列。

package cn.mldn.demo;

import java.util.HashSet;

import java.util.Set;

public class TestDemo {

    public static void main(String[] args)throws Exception {

        Set all = new HashSet() ;

        all.add("HELLO") ;

        all.add("HELLO") ;  // 保存了重复数据

        all.add("WORLD") ;

        all.add("小金子") ;

        all.add("小谢子") ;

        System.out.println(all);

    }}

         使用HashSet是不能够保存重复数据的。而且保存的数据没有任何的顺序。

3.2、排序存放的子类:TreeSet(10%)

         如果希望里面的数据排序,则可以使用TreeSet子类。

package cn.mldn.demo;

import java.util.Set;

import java.util.TreeSet;

public class TestDemo {

    public static void main(String[] args)throws Exception {

        Set all = new TreeSet() ;

        all.add("B") ;

        all.add("D") ;  // 保存了重复数据

        all.add("E") ;

        all.add("A") ;

        all.add("C") ;

        System.out.println(all);

    }}

         但是对于排序一般意义不大,所以使用的时候还是以HashSet为主。

3.3、关于数据排序的说明

         使用TreeSet可以实现集合中数据排序的保存,那么在之前使用的是String型数据,下面使用自定义类。但是这个类如果要想正常的使用TreeSet保存,那么一定要在此类上实现java.lang.Comparable接口,以区分大小。

         但是在此时覆写compareTo()方法的时候必须注意到:所有的属性都必须进行比较,否则就会出现部分属性内容相同也会认为是同一对象的情况,造成数据的保存错误。

范例:使用自定义类

package cn.mldn.demo;

import java.util.Set;

import java.util.TreeSet;

class Person implements Comparable {

    private String name ;

    private int age ;

    public Person(String name,int age) {

        this.name = name ;

        this.age = age ;

    }

    @Override

    public String toString() {

        return "姓名:" +this.name + ",年龄 :" + this.age + "\n" ;

    }

    @Override

    public int compareTo(Person o) {

        if (this.age > o.age) {

           return -1 ;

        } else if (this.age < o.age) {

           return 1 ;

        }

        return this.name.compareTo(o.name);

    }

}

public class TestDemo {

    public static void main(String[] args)throws Exception {

        Set all = new TreeSet() ;

        all.add(new Person("张三",20)) ;

        all.add(new Person("李四",21)) ;

        all.add(new Person("赵六",21)) ; // 年龄重复

        all.add(new Person("王五",19)) ;

        all.add(new Person("王五",19)) ; // 彻底重复

        System.out.println(all);

    }

}

         通过此时的程序也可以得出一个结论:TreeSet使用过程之中一定要使用到Comparable接口,而且TreeSet集合里面是依靠Comparable接口的compareTo()方法返回的数据来区分是否为重复数据。

3.4、关于重复数据的说明

         Set子接口之中不允许保留重复数据,之前使用的TreeSet子类虽然依靠了Comparable接口进行重复数据判断,但是此判断的方式也只是针对于TreeSet这种排序结构起作用,而真正意义上的排序操作是不依靠接口的,而是依靠Object类之中的两个方法:

                   · 取得对象的hash码:public int hashCode();

                   · 对象比较:public boolean equals(Object obj);

         在判断对象是否重复的过程之中,其基本流程如下:

                   · 首先使用要查询对象的hashCode与集合之中的保存对象的每一个hashCode进行比较;

                   · 如果hashCode相同,则再使用equals()方法进行内容的比较。



 

 

范例:重复对象判断

package cn.mldn.demo;

import java.util.HashSet;

import java.util.Set;

class Person {

    private String name ;

    private int age ;

    public Person(String name,int age) {

        this.name = name ;

        this.age = age ;

    }

    @Override

    public String toString() {

        return "姓名:" +this.name + ",年龄 :" + this.age + "\n" ;

    }

    @Override

    public int hashCode() {

        final int prime = 31;

        int result = 1;

        result = prime * result + age;

        result = prime * result + ((name ==null) ? 0 : name.hashCode());

        return result;

    }

    @Override

    public boolean equals(Object obj) {

        if (this == obj)

           return true;

        if (obj ==null)

           return false;

        if (getClass() != obj.getClass())

           return false;

        Person other = (Person) obj;

        if (age != other.age)

           return false;

        if (name ==null) {

           if (other.name != null)

               return false;

        } else if (!name.equals(other.name))

           return false;

        return true;

    }

}

public class TestDemo {

    public static void main(String[] args)throws Exception {

        Set all = new HashSet() ;

        all.add(new Person("张三",20)) ;

        all.add(new Person("李四",21)) ;

        all.add(new Person("赵六",21)) ; // 年龄重复

        all.add(new Person("王五",19)) ;

        all.add(new Person("王五",19)) ; // 彻底重复

        System.out.println(all);

    }

}

         任何情况下如果是对象的重复判断,永恒都使用hashCode()和equals()。




4、集合输出接口

虽然在Collection接口之中提供有将数据变为对象数组的输出形式,但是所有的开发者基本上都不会使用此类访问,因为对于集合的输出有四类主要操作:Iterator、ListIterator、Enumeration、foreach。

4.1、迭代输出:Iterator(核心,95%)

          Iterator是最为常用的一个输出接口,而这个接口的定义如下:

public interface Iterator {

    public boolean hasNext() ;  // 判断是否有数据

    public E next() ;   // 取数据

    public void remove() ;  // 删数据

}

         在之前所学习过的Scanner类就是Iterator接口的子类,但是在Iterator接口里面最常用的只有两个方法:hasNext()、next(),而remove()基本上一次都用不到。

         但是Iterator本身是一个接口,如果要想为此接口实例化对象,则需要使用Collection接口定义的方法:

                   · 取得Iterator接口对象:public Iterator iterator();

范例:利用Iterator输出数据

package cn.mldn.demo;

import java.util.ArrayList;

import java.util.Iterator;

import java.util.List;

public class TestDemo {

    public static void main(String[] args)throws Exception {

        List all = new ArrayList() ;

        all.add("HELLO") ;

        all.add("HELLO") ;

        all.add("WORLD") ;

        all.add("你好") ;

        Iterator iter = all.iterator() ;

        while (iter.hasNext()) {

            String str = iter.next() ;

            System.out.println(str);

        }

    }

}

         那么此时的操作形式就是在集合输出的标准形式。以后不管是何种开发,只要面对集合的输出操作,不需要做任何思考,永恒使用Iterator输出。

4.2、双向迭代输出:ListIterator(理解,0.01%)

         Iterator只能够完成由前向后的单向输出,而ListIterator可以完成双向的输出,ListIterator定义如下:

public interface ListIterator

extends Iterator

         ListIterator是Iterator的子接口,所以在此接口里面重点只观察两个方法:

                   · 判断是否有前一个数据:public boolean hasPrevious();

                   · 取出前一个数据:public E previous()。

         但是如果要想取得ListIterator接口对象,那么只能够依靠List接口完成。

package cn.mldn.demo;

import java.util.ArrayList;

import java.util.List;

import java.util.ListIterator;

public class TestDemo {

    public static void main(String[] args)throws Exception {

        List all = new ArrayList() ;

        all.add("HELLO") ;

        all.add("HELLO") ;

        all.add("WORLD") ;

        all.add("你好") ;

        System.out.print("由前向后输出:");

        ListIterator iter = all.listIterator() ;

        while (iter.hasNext()) {

            String str = iter.next() ;

            System.out.print(str + "、");

        }

        System.out.print("\n由后向前输出:");

        while (iter.hasPrevious()) {

            String str = iter.previous() ;

            System.out.print(str + "、");

        }

    }

}

         如果要想进行由后向前的输出一定要首先发生由前向后的输出,实在是罗嗦,没用。

4.3、古老的输出:Enumeration(重点,4.98%)

         Enumeration是在JDK 1.0的时候就提出的一个输出接口,最早是将其称为枚举输出。不过后来随着发展,Enumeration使用的几率越来越少(你们一定会用的),那么Enumeration接口定义如下:

public interface Enumeration {

    public boolean hasMoreElements() ;  // 是否有下一个元素

    public E nextElement() ;            // 取出元素

}

         但是如果要想取得Enumeration接口实例也是不能够依靠集合接口,只能够依靠Vector类,在Vector子类里面定义了如下方法:public Enumeration elements()

范例:使用Enumeration输出

package cn.mldn.demo;

import java.util.Enumeration;

import java.util.Vector;

public class TestDemo {

    public static void main(String[] args)throws Exception {

        Vector all = new Vector() ;

        all.add("HELLO") ;

        all.add("HELLO") ;

        all.add("WORLD") ;

        all.add("你好") ;

        Enumeration enu = all.elements() ;

        while(enu.hasMoreElements()) {

            String data = enu.nextElement() ;

            System.out.println(data);

        }

    }

}

         如果不到必须使用Enumeration接口的时候能不用还是不用它,都使用Iterator比较好。

4.4、新的输出:foreach(理解,0.01%)

         在之前使用过foreach进行数组的输出,但是对于foreach而言也可以进行集合数据的输出操作,只不过很少有人这样去做。尤其针对于初学者,还是使用标准的Iterator会更好一些。

package cn.mldn.demo;

import java.util.ArrayList;

import java.util.List;

public class TestDemo {

    public static void main(String[] args)throws Exception {

        List all = new ArrayList() ;

        all.add("HELLO") ;

        all.add("HELLO") ;

        all.add("WORLD") ;

        all.add("你好") ;

        for (String str : all) {

            System.out.println(str);

        }

    }

}

         以上的操作谨慎使用,能不用最好。




5、Map集合接口

Collection每次只能够保存一个对象,而Map每次可以保存一对对象。那么这对对象会按照“key=value”的形式进行存储,随后可以通过key找到对应的value,就好比电话号码本一样,例如,现在存了如下数据:

                   · name = 张三,tel = 110;

                   · name = 李四,tel = 119;

         现在找到了张三(找到了name),就可以找到与之对应的电话(tel),而这样的操作可以通过Map集合表示(public interface Map)。在使用Map接口的时候需要设置两个泛型类型,一个是key的类型,另外一个是value的类型,而在Map接口中定义了如下常用方法。

No.

方法名称

类型

描述

1

public V put(K key, V value)

普通

集合之中保存数据

2

public V get(Object key)

普通

根据key取得对应的value

3

public Set keySet()

普通

取得全部的key,key不能重复

4

public Collection values()

普通

取得全部的value

5

public Set> entrySet()

普通

将Map集合变为Set集合

         而在Map接口下又有两个常见的子类:HashMap、Hashtable。

5.1、新的子类:HashMap(90%)

         HashMap是Map接口中最为常用的一个子类,下面将使用HashMap验证Map的使用操作。

范例:保存数据

package cn.mldn.demo;

import java.util.HashMap;

import java.util.Map;

public class TestDemo {

    public static void main(String[] args)throws Exception {

        Map map = new HashMap();

        map.put(1, "张三");

        map.put(1, "李四"); // key重复

        map.put(2, "王五");

        map.put(3, null);

        map.put(null, "赵六");

        System.out.println(map);

    }

}

         在使用Map集合的时候如果发生了key重复的问题,那么会使用新的值替换掉旧的值。但是从实际来讲,设置在Map之中的数据主要是为了查找使用。

         Collection设置数据的目的主要是为了输出,而Map设置数据的目的主要是为了查找。

范例:查找数据

package cn.mldn.demo;

import java.util.HashMap;

import java.util.Map;

public class TestDemo {

    public static void main(String[] args)throws Exception {

        Map map = new HashMap();

        map.put(1, "张三");

        map.put(1, "李四"); // key重复

        map.put(2, "王五");

        map.put(3, null);

        map.put(null, "赵六");

        System.out.println(map.get(1));

        System.out.println(map.get(null));

        System.out.println(map.get(200));   // 没有返回null

    }

}

         整个过程之中都是可以进行null操作的。

5.2、旧的子类:Hashtable(10%)

         Hashtable与Vector、Enumeration一样,都是最早提供的集合操作类,在JDK 1.2之后为了保护其可以继续使用,所以让Hashtable多实现了一个Map接口。

范例:验证Hashtable

package cn.mldn.demo;

import java.util.Hashtable;

import java.util.Map;

public class TestDemo {

    public static void main(String[] args)throws Exception {

        Map map = new Hashtable();

        map.put(1, "张三");

        map.put(1, "李四"); // key重复

        map.put(2, "王五");

        System.out.println(map.get(1));

        System.out.println(map.get(200));   // 没有返回null

    }

}

         在Hashtable的操作之中可以发现,里面是不能够存在有null数据的。

面试题:请解释HashMap和Hashtable区别?

No.

区别

HashMap

Hashtable

1

推出时间

JDK 1.2时推出

JDK 1.0时推出

2

性能

采用异步处理方式,性能较高

采用同步处理方式,性能较低

3

安全性

数据安全性差

数据安全性高

4

处理null

允许保存null

不允许保存null,会出现NullPointerException

         考虑到日后的开发异步开发居多,所以以HashMap类为主。

5.3、关于Map集合的输出说明(核心)

         在Map接口里面存在有一个keySet()的方法,此方法返回的是所有的key的数据,并且是以Set集合的形式返回,于是下面就使用此方法输出数据。

package cn.mldn.demo;

import java.util.HashMap;

import java.util.Iterator;

import java.util.Map;

import java.util.Set;

public class TestDemo {

    public static void main(String[] args)throws Exception {

        Map map = new HashMap();

        map.put(1, "张三");

        map.put(2, "李四");

        map.put(3, "王五");

        Set set = map.keySet() ;   // 取得全部的key

        Iterator iter = set.iterator() ;

        while (iter.hasNext()) {

            Integer key = iter.next() ;

            System.out.println(key + " --> " + map.get(key));

        }

    }

}

         就本程序而言,已经实现了Map集合的输出操作,但是这个输出操作存在以下问题:首先取得了全部key,需要进行迭代输出,而且每一个key又要去查询集合中对应的value(循环),所以这样的输出形式是不可取的。

         如果要想输出Map集合,那么一定还是需要使用到Iterator接口,可是Map接口里面并没有定义像Collection接口之中定义的iterator()方法,那么下面就需要分析一下Collection和Map的数据保存区别。


         可以发现在Map接口里面存在有一个static定义的子接口:Map.Entry,而所有的key和value都自动的封装在了此接口对象之中,而在Map.Entry接口里面存在有两个方法:

                   · 取得包装的key:public K getKey();

                   · 取得包装的value:public V getValue();

关于Map接口使用Iterator输出的过程:

         1、   首先使用Map集合之中的entrySet()方法将Map集合变为Set集合,而此时Set集合中的每一个元素类型都是Map.Entry接口实例;

         2、   利用Set接口的iterator()方法取得Iterator接口对象,同时Iterator中操作的类型依然是Map.Entry;

         3、   利用Iterator进行迭代输出,取出每一个Map.Entry对象,并且利用getKey()和getValue()方法取出数据。

范例:利用Iterator输出Map集合

package cn.mldn.demo;

import java.util.HashMap;

import java.util.Iterator;

import java.util.Map;

import java.util.Set;

public class TestDemo {

    public static void main(String[] args)throws Exception {

        Map map = new HashMap();

        map.put(1, "张三");

        map.put(2, "李四");

        map.put(3, "王五");

        Set> set = map.entrySet();

        Iterator> iter = set.iterator();

        while (iter.hasNext()) {

            Map.Entry me = iter.next();

            System.out.println(me.getKey() + " --> " + me.getValue());

        }

    }

}

         这一程序在工作之中一定会出现,建议下面多写几次,同时一定要记住Map.Entry的作用。

5.4、关于Map集合之中key的说明

         通过之前的代码演示发现一直都是使用Integer作为key的类型,而且Integer本身也是系统类。那么在实际上Map也可以使用自定义类型作为key。但是此时必须有一个要求:由于map集合根据key的查找属于对象的匹配过程,所以作为自定义的key类型,类一定要覆写Object类的hashCode()和equals()两个方法。

package cn.mldn.demo;

import java.util.HashMap;

import java.util.Map;

class Person {

    private String name ;

    private int age ;

    public Person(String name,int age) {

        this.name = name ;

        this.age = age ;

    }

    @Override

    public String toString() {

        return "姓名:" +this.name + ",年龄:" + this.age ;

    }

    @Override

    public int hashCode() {

        final int prime = 31;

        int result = 1;

        result = prime * result + age;

        result = prime * result + ((name ==null) ? 0 : name.hashCode());

        return result;

    }

    @Override

    public boolean equals(Object obj) {

        if (this == obj)

           return true;

        if (obj ==null)

           return false;

        if (getClass() != obj.getClass())

           return false;

        Person other = (Person) obj;

        if (age != other.age)

           return false;

        if (name ==null) {

           if (other.name != null)

               return false;

        } else if (!name.equals(other.name))

           return false;

        return true;

    }

}

public class TestDemo {

    public static void main(String[] args)throws Exception {

        Map map = new HashMap();

        map.put(new Person("张三", 20),new String("ZS"));

        System.out.println(map.get(new Person("张三", 20)));

    }

}

         以上的代码只是在一次重复强调了hashCode()和equals()的作用,但是从实际的角度来看,作为key的类型99%的情况下都会使用String表示,或者使用Integer等系统类表示。




6、Collections工具类

在java.util包里面有一个Collections类。

package cn.mldn.demo;

import java.util.ArrayList;

import java.util.Collections;

import java.util.List;

public class TestDemo {

    public static void main(String[] args)throws Exception {

        List all = new ArrayList() ;

        Collections.addAll(all, "HELLO", "WORLD", "你好");

        Collections.reverse(all);

        System.out.println(all);

    }

}

         虽然Collections提供了集合的工具类支持,但是此类的存在意义并不大,也很少去使用,作为知识知道就行了。

面试题:请解释Collection和Collections区别?

         · Collection是集合操作的父接口;

         · Collections是集合操作的工具类,提供了各种集合的操作方法支持。




7、Stack

栈是一种先进后出的数据结构。Stack属于Vector一个子类。但是在进行方法操作的时候需要使用自己扩充方法:

                   · 入栈:public E push(E item);

                   · 出栈:public E pop()。

范例:观察栈操作

package cn.mldn.demo;

import java.util.Stack;

public class TestDemo {

    public static void main(String[] args)throws Exception {

        Stack all = new Stack();

        all.push("A");

        all.push("B");

        all.push("C");

        System.out.println(all.pop());

        System.out.println(all.pop());

        System.out.println(all.pop());

        System.out.println(all.pop());  // 没数据了,EmptyStackException

    }

}

         在Android之中每一个打开的界面都会自动的入栈保存,所以当后退的时候就是一个出栈过程。




8、Properties

Properties是Hashtable的子类,在Hashtable操作的过程之中,key和value都可以保存任意的对象,但是在Properties之中key和value只能够是String型数据,而且操作的方法如下:

                   · 设置属性:public Object setProperty(String key, String value);

                   · 取得属性:public String getProperty(String key),没有属性返回null;

                   · 取得属性:public String getProperty(String key, String defaultValue),没有返回默认值。

范例:验证Properties使用

package cn.mldn.demo;

import java.util.Properties;

public class TestDemo {

    public static void main(String[] args)throws Exception {

        Properties pro = new Properties();

        pro.setProperty("BJ", "北京");

        pro.setProperty("TJ", "天津");

        System.out.println(pro.getProperty("BJ"));

        System.out.println(pro.getProperty("GZ"));

        System.out.println(pro.getProperty("GZ","没有信息"));

    }

}

         而通过Properties类设置的属性也是可以通过IO操作进行输出的,定义了如下输出方法:

                   ·保存属性:public void store(OutputStream out, String comments) throws IOException

范例:将属性保存到文件

package cn.mldn.demo;

import java.io.File;

import java.io.FileOutputStream;

import java.util.Properties;

public class TestDemo {

    public static void main(String[] args)throws Exception {

        Properties pro = new Properties();

        pro.setProperty("BJ", "北京");

        pro.setProperty("TJ", "天津");

        pro.store(new FileOutputStream(new File("D:" + File.separator

                + "area.properties")), "Area Info");

    }

}

         属性文件的后缀一般都是“*.properties”。

         既然可以通过输出流输出文件信息,那么也可以通过输入流读取文件信息,方法如下:

                   ·读取属性:public void load(InputStream inStream) throws IOException

package cn.mldn.demo;

import java.io.File;

import java.io.FileInputStream;

import java.util.Properties;

public class TestDemo {

    public static void main(String[] args)throws Exception {

        Properties pro = new Properties();

        pro.load(new FileInputStream(new File("D:" + File.separator

                + "area.properties")));

        System.out.println(pro.getProperty("BJ"));

        System.out.println(pro.getProperty("GZ"));

    }

}

         需要注意的是在*.properties文件之中是不能够直接使用中文的,必须转码,如果要转码可以使用一个指定的转码工具“native2ascii.exe”。日后的开发之中一定会使用到属性文件进行提示数据的保存,所以以上代码非常重要。



你可能感兴趣的:(Java系列(二十)__Java类集)