run_wind

导航

黑马程序员--第一阶段5.JavaAPI--第15天

-------------------- android培训java培训、期待与您交流!--------------------

 

 

HashtableProperties

  • Hashtable也是一种高级数据库结构,用来快速检索数据。Hashtable不仅可以像Vector一样动态存储一系的对象,而且对存储的每一个对象(称之为值)都要安排另一个对象(称之为关键字)与之相关联。
  • Hashtable对象中存储数据,使用的是Hashtable.put(Object key,Object value)方法,从Hashtable中检索数据,使用Hashtable.get(Object key)方法。值和关键字都可以是任何类型的非空的对象。Hashtable中的关键字不能相同

Hashtable numbers=new Hashtable();

numbers.put(“one”,new Integer(1));

numbers.put(“two”,new Integer(2));

numbers.put(“three”,new Integer(3));

要检索其中”tow”关键字对应的数据,看下面的代码就能明白:

Integer n=(Integer)numbers.get(“two”)

if(n!=null)

{

       System.out.println(“two = ”+n);

}

  • 想要成功地从Hashtable中检索数据,用作关键字的对象必须正确覆盖了Object.hashCode方法和Object.equals方法。覆盖Object.equals道理不难想象,检索数据时必须比较所用关键字是否与存储在Hashtable中的某个关键字相等,如果两个关键字对象不能正确判断是否相等,检索是不可能正确的。Object.hashCode方法返回一个叫散列码的值,这个值是由对象的地址以某种方式转换来的。内容相同的两个对象,既然是两个对象,地址就不可能一样,所以Object.hashCode返回的值也不一样。要想两个内容相同的Object子类对象的hashCode方法返回一样的散列码,子类必须覆盖Object.hashCode方法。用于关键字的类,如果它的两个String对象的内容不相等,它们的hashCode的返回值也不相等,如果两个String对象的内容相等,它们的hashCode的返回值也相等,所以,我们在实现自己编写的关键字类的hashCode方法时,可以调用这个关键字类的String类型的成员变量的hashCode方法来计算关键字类的hashCode返回值。注意:StringBuffer类没有按照关键字类的要求覆盖hashCode方法,即使两个StringBuffer类对象的内容相等,但这两个对象的hashCode方法返回值却不相等。所以,我们不能用StringBuffer作为关键字类。

实例:

MyKey.java

class MyKey

{

    private String name;

    private int age;

    public MyKey(String name,int age)

    {

           this.name=name;

           this.age=age;

    }

    public String toString()

    {

           return new String(name+","+age);

    }

    public boolean equals(Object obj)

    {

           if(obj instanceof MyKey)

           {

                  MyKey objTem=(MyKey)obj;

                  if(name.equals(objTem.name)&&age==objTem.age)

                         return true;

                  else

                         return false;

           }

           else

                  return false;

    }

    public int hashCode()

    {

           return name.hashCode()+age;

    }

}

上面的代码实现了我们的目的:如果两个人名字和年龄都相同,我们就认为他们是同一个人。

下面的类使用MyKey 类作为关键字类,取出所有关键字的集合和取出所有值的集合:

HashtableTest.java

import java.util.*;

public class HashtableTest

{

    public static void main(String[] args)

    {

           Hashtable numbers=new Hashtable();

           numbers.put(new MyKey("Zhangsan",18),new Integer(1));

           numbers.put(new MyKey("Lisi",15),new Integer(2));

           numbers.put(new MyKey("Wangwu",20),new Integer(3));

          

           Enumeration e=numbers.keys();//Hashtable中的keys方法以Enumeration接口的方式返回Hashtable对象的所有关键字

           while(e.hasMoreElements())

           {

                  MyKey key=(MyKey)e.nextElement();

                  System.out.print(key+"=");//打印key时,会默认调用key.toString()方法,这个方法里面是什么内容打印出来的就是什么内容

                  System.out.println(numbers.get(key));//MyKey类中重写的equalshashCode方法是在这个get方法使用时要调用的,由系统自动调用

           }

           System.out.println(numbers.get(new MyKey("Wangwu",20)));//新建一个对象作为关键字传给get方法,用于取出numbers对象中的这个关键字所对应的值

                                                                                                             //如果没有在MyKey类中覆盖equalshashCode方法,则取不出对应的值

           testABC abc=new testABC();

           System.out.println(abc);//打印abc对象时,会默认调用这个对象的toString()方法,这个方法里面是什么内容打印出来的就是什么内容

    }    

}

class testABC

{

    String a="戴振良";

    String b="你好";

    public String toString()

    {

           return a+b;

    }

}

 

Properties

         PropertiesHashtable的子类,它增加了将Hashtable对象中的关键字、值保存到文件和文件中读取关键字、值到Hashtable对象中的方法。在大多数应用程序都有选项设置,就是在程序退出时将功能/设置值存储到文件,程序启动时将功能/设置值读取到了内存,程序按新的设置运行,如: 

图片 

  • 如果要用Properties.store方法存储Properties对象中的内容,每个属性的关键字和值都必须是String类型。
  • 实例:编写一个程序,每次运行时打印出运行的次数。

import java.util.Properties;

import java.io.*;

public class PropertiesFile

{

                     Properties settings=new Properties();

            try{      //FileInputStream类:从文件系统中的某个文件中获得输入字节,该类是InputStream类的子类

                   settings.load(new FileInputStream("count.txt"));}//load( )方法功能:从输入流中读取属性列表(键和元素对)

            catch(Exception e){

                   settings.setProperty("count",String.valueOf(0)); //setProerty方法是调用Hashtableput方法,但是这个方法的参数必须是String类型的。这里把0转换为String对象用String.valueOf 方法,这比new Integer(0).toString()方法要方便,而String.valueOf方法实际上是调用IntegertoString方法来进行转换的   

            }

            //settings.get("count");//get方法是从Hashtable中继承来的,该方法返回的值是Oject类型的

            //getProperty方法与get方法功能类似,只不过getProperty方法返回的值是String类型的

            int c=Integer.parseInt(settings.getProperty("count"))+1;

            System.out.println("这是第"+c+"次运行");

           

            //settings.put("count",new Integer(c).toString());//这个方法可以接受非字符串的数据作为参数,因为Properties中存储的关键字和值都必须是字符串,所以用下面的setProperty方法比较好。

            settings.setProperty("count",new Integer(c).toString());//这个方法的参数必须都是字符串类型的

            try{

                   settings.store(new FileOutputStream("count.txt"),"Program is used:");//在这句代码里,如果系统中没有count.txt文件存在,则系统会自动产生这个文件

            }

            catch(Exception a){

                   a.printStackTrace();

            }

     }    

}

 

程序每次启动时都去读取那个记录文件,直接取出文件中所记录的运行次数并加1后,又重新将新的运行次数存回文件。由于第一次运行时硬盘上还没有那个记录文件,程序去读取那个记录文件时会报出一个异常,我们就在处理异常的语句中将属性的值设置为0,表示程序以前还没有运行过。如果要用到Properties类的store方法进行存储,每个属性的关键字和值都必须是字符串类型的,所以上面的程序没有用从父类Hashtable继承到的putget方法进行属性的设置与读取,而直接用了Properties类的setPropertygetProperty方法进行属性的设置与读取。一般有使用次数限制的共享软件的程序代码基本上都是这么做的,只不过它们把记录次数的这个文件隐藏在某个不容易发现的地方,例如保存在注册表里或某个系统文件里,只要找到这个地方,删除这个文件或注册表项,这个软件又可以被使用了。

System类与Runtime

System

java不支持全局函数和变量,java设计者将一些系统相关的重要函数和变量收集到了一个统一的类中,这就是System类,System类中的所有成员都是静态的,当我们要引用这些变量和方法时,直接使用System类名作前缀,如前面已经使用到的标准输入和输出的inout变量。

 

System类的常用方法:

  • exit(int status)方法,提前终止虚拟机的运行。对于发生了异常情况而想终止虚拟机的运行,传递一个非零值作为参数。对于用户正常操作下想终止虚拟机的运行,则传递零作为参数。
  • currentTimeMillis方法返回自197011000秒起至今的以毫秒为单位的时间,这是一个long类型的大数值,在计算机内部,只有数值,没有真正的日期类型及其他各种类型,也就是说,我们平常用到的日期本质上就是一个数值,但是通过这个数值,能够推算出其对应的具体日期时间。
    可以用currentTimeMillis方法检测一段程序代码运行时所花费的时间:
  •        long startTime=System.currentTimeMillis( );
    ……  //代码段
    long endTime=System.currentTimeMillis( );
    System.out.println(“
    总计用时:”+(endTime-startTime)+”毫秒”);
  • getProperties方法与Java的环境属性
  • getProperties方法获得当前Java虚拟机的系统属性。如果大家明白Windows的环境属性,如pathclasspath就是其中的两个环境变量,每一个属性都是变量与值成对的形式出现的。
  • setProperties方法设置当前Java虚拟机的系统属性。
  • getPropertiessetProperties这两个方法返回值和参数分别是Properties类的一个实例。Properties实例对象中存储着Java虚拟机所有的系统属性的变量和值对的情况。
  • 同样的道理,Java作为一个虚拟的操作系统,它也有自己的环境属性,PropertiesHashtable的子类,正好可以用于存储环境属性中的多个变量、值成对格式的数据,getProperties方法返回值是包含了当前虚拟机的所有环境属性的Properties类型的对象。
  • 实例:打印出当前虚拟机的所有环境属性的变量和值。

import java.util.*;//Properties位于此包中

public class TestProperties {

       public static void main(String args[]){

              System.setProperty("haha","hello");//增加系统属性,第一个参数为变量名,第二个为值

              Properties sp=System.getProperties();//获取当前java虚拟机的系统属性

              Enumeration e=sp.propertyNames();//获取所有的属性名称

              while(e.hasMoreElements()){

                     String key=(String)e.nextElement();//获取e中的元素,也就是java虚拟机的系统属性名称

                     System.out.println(key+"="+sp.getProperty(key));//输出(名称+"="+值)

              }

              Process p=null;  //Process类代表Java虚拟机启动的进程启动的子进程

              try{

              p=Runtime.getRuntime().exec("notepad.exe TestProperties.java");

              Thread.sleep(5000);//进程睡眠5

              }

              catch(Exception a){

                     a.printStackTrace();

              }

              p.destroy();//这个方法为关闭实例p所对应的进程

       }

}

  • Windows中,很容易增加一个新的环境属性,但如何为Java虚拟机增加一个新的环境属性呢?在命令行窗口中直接运行Java命令,会看到有一个“-D<name>=<value>格式的选项可以设置新的系统环境属性。如:
             java –Dname=hello TestProperties
  • 增加两个环境属性的格式:java –DAAA=bbb –DCCC=ddd TestProperties

Runtime

Runtime类封装了Java命令本身运行的进程,也就是封装了Java虚拟机进程,一个Java 虚拟机对应一个Runtime实例对象,其中的许多方法与System中的方法相重复。不能直接创建Runtime实例,但是可以通过静态方法Runtime.getRuntime获得正在运行的Runtime对象的引用。

Exec方法,Java命令运行后,本身是多任务操作系统上的一个进程,在这个进程中启动一个新的进程(这个进程就叫子进程),即执行其他程序时使用exec方法。exec方法返回一个代表子进程的Process类对象,通过这个对象,Java进程可以与子进程交互。

实例:

运行后程序启动一个子进程:用Windows的记事本程序打开了我们的源程序,并在5秒种后销毁该子进程,记事本程序被关掉。

public class TestRunTime {

 

    public static void main(String [] args) {

           Process p=null; //Process类代表Java虚拟机启动的进程启动的子进程

           try{

                  p=Runtime.getRuntime().exec("notepad.exe TestRuntime.java");

                  Thread.sleep(5000);//把线程暂停5

           }catch(Exception e){

                  System.out.println(e.getMessage());

           }

           p.destroy();//这个方法为关闭实例p所对应的进程

    }   

}

由于程序不能直接创建类Runtime的实例,所以可以保证我们只会产生一个Runtime的实例对象,而不能产生多个实例对象,这种情况就是单态设计模式。我们可以按照单态设计模式思想来设想一下Runtime类在内部是如何构造Runtime类的对象实例的。

 

 

-------------------- android培训java培训、期待与您交流!--------------------

 

posted on 2012-04-25 11:02  run_wind  阅读(159)  评论(0编辑  收藏  举报