黑马程序员——Java 常用类库

来源:互联网 发布:高性能网络编程2 编辑:程序博客网 时间:2024/06/05 14:26

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


Java常用类库

1. String、StringBuffer和StringBuilder类

1.1 String类常用方法

 

前面已经详细说了String类的各种概念,其中一条特性就是String的内容一旦声明则不可改变,改变的只是内存地址的指向,那么如果现在想要让字符串的内容可以修改,则必须使用StringBuffer类完成。下面是String类的常用方法。

 

 

构造方法摘要

 

public String(byte[] bytes)

通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String。

String str05 = new String(newbyte[]{0x61, 0x62, 0x63, 0x64, 0x65});

public String(byte[] bytes, Charset charset)

通过使用指定的 charset 解码指定的 byte 数组,构造一个新的 String。

public String(byte[] bytes, int offset, int length)

通过使用平台的默认字符集解码指定的 byte 子数组,构造一个新的 String。

String str06 = new String(newbyte[]{0x61, 0x62, 0x63, 0x64, 0x65}, 1, 3); // 0x61在ASC表中,对应字符"a"; 1表示起始位置,3表示长度

public String(char[] value)

分配一个新的 String,使其表示字符数组参数中当前包含的字符序列。该字符数组的内容已被复制;后续对字符数组的修改不会影响新创建的字符串。

String str03 = new String(newchar[]{'s','t','r','0','3'});

public String(char[] value, int offset, int count)

分配一个新的 String,它包含取自字符数组参数一个子数组的字符。

String str = new String(newchar[]{'s','t','r','0','4'}, 1, 3);

public String(StringBuffer buffer)

分配一个新的字符串,它包含字符串缓冲区参数中当前包含的字符序列。

public String(StringBuilder builder)

分配一个新的字符串,它包含字符串生成器参数中当前包含的字符序列。

String str1 = new String(new StringBuffer("StringBuffer"));String str2 = new String(new StringBuilder("StringBuilder"));

 

方法摘要

 

public char[] toCharArray()

将此字符串转换为一个新的字符数组。

String str = "Enter";char[] c = str.toCharArray();for (int i = 0; i < c.length; i++) {    System.out.print(c[i] +" ");}System.out.println();String s1 = new String(c);    // 将全部字符数组变为StringString s2 = new String(c,0,2);// 将部分字符数组变为Stringpublic char charAt(int index)

返回指定索引处的 char 值。索引范围为从 0 到 length() - 1。序列的第一个 char 值位于索引 0 处,第二个位于索引 1 处,依此类推,这类似于数组索引。

String str = "Enter";System.out.println(str.charAt(2));

public byte[]getBytes()

使用平台的默认字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。

byte[] bytes = str.getBytes();

public int length()

返回此字符串的长度。长度等于字符串中Unicode代码单元的数量。

注意:length和length()的区别:在数组操作中,使用length取得数组的长度,而字符串调用length()是一个方法。

public int indexOf(String str)

返回指定子字符串在此字符串中第一次出现处的索引。返回的整数是  this.startsWith(str, k)为 true 的最小 k 值。

str.indexOf("e");

public int indexOf(String str, int fromIndex)

返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始。返回的整数是满足下式的最小 k 值:

     k >= Math.min(fromIndex, this.length()) && this.startsWith(str, k)

如果不存在这样的 k 值,则返回 -1。

str.indexOf("e",4);

public Stringtrim()

返回字符串的副本,忽略前导空白和尾部空白。

String str = "  Enter    ";System.out.println(str.trim());//Enter

public Stringsubstring(int beginIndex)

返回一个新的字符串,它是此字符串的一个子字符串。该子字符串从指定索引处的字符开始,直到此字符串末)。beginIndex -起始索引(包括)。

public Stringsubstring(int beginIndex, int endIndex)

返回一个新字符串,它是此字符串的一个子字符串。该子字符串从指定的 beginIndex 处开始,直到索引 endIndex - 1 处的字符。因此,该子字符串的长度为 endIndex-beginIndex。

String str = "  Enter your name    ";System.out.println(str.substring(6));System.out.println(str.substring(0,5));

public String[]split(String regex)

根据给定正则表达式的匹配拆分此字符串。

String[] strs = str.split(" ");for (String s : strs) {    System.out.println(s);}

public StringtoLowerCase()

使用默认语言环境的规则将此 String 中的所有字符都转换为小写。这等效于调用 toLowerCase(Locale.getDefault())。

public StringtoUpperCase()

使用默认语言环境的规则将此 String 中的所有字符都转换为大写。此方法等效于 toUpperCase(Locale.getDefault())。

System.out.println("将\"Enter your name\"转换成小写:"+str.toLowerCase());System.out.println("将\"Enter your name\"转换成大写:"+str.toUpperCase());

public booleanstartsWith(String prefix)

测试此字符串是否以指定的前缀开始。

public booleanendsWith(String suffix)

测试此字符串是否以指定的后缀结束。

public booleanequals(Object anObject)

将此字符串与指定的对象比较。当且仅当该参数不为 null,并且是与此对象表示相同字符序列的 String对象时,结果才为 true

public booleanequalsIgnoreCase(String anotherString)

将此 String与另一个 String比较,不考虑大小写。如果两个字符串的长度相同,并且其中的相应字符都相等(忽略大小写),则认为这两个字符串是相等的。

publicStringreplaceAll(String regex,String replacement)

使用给定的 replacement替换此字符串所有匹配给定的正则表达式的子字符串。

 

关于String类的更多方法,在使用时可参考API文档。

 

1.2 StringBuffer

 

StringBuffer类是线程安全的可变字符序列。一个类似于 String的字符串缓冲区,但不能修改。虽然在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。可将字符串缓冲区安全地用于多个线程。可以在必要时对这些方法进行同步,因此任意特定实例上的所有操作就好像是以串行顺序发生的,该顺序与所涉及的每个线程进行的方法调用顺序一致。

StringBuffer上的主要操作是 append insert 方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串缓冲区中。append方法始终将这些字符添加到缓冲区的末端;而 insert方法则在指定的点添加字符。每个字符串缓冲区都有一定的容量。只要字符串缓冲区所包含的字符序列的长度没有超出此容量,就无需分配新的内部缓冲区数组。如果内部缓冲区溢出,则此容量自动增大。从 JDK 5开始,为该类补充了一个单个线程使用的等价类,即StringBuilder。与该类相比,通常应该优先使用 StringBuilder类,因为它支持所有相同的操作,但由于它不执行同步,所以速度更快。

下面分析StringBuffer类的方法:

public final class String extends Objectimplements Serializable, Comparable<String>, CharSequencepublic final class StringBuffer extends Objectimplements Serializable, CharSequencepublic final class StringBuilder extends Objectimplements Serializable, CharSequence

 

构造方法摘要

 

publicStringBuffer()

构造一个其中不带字符的字符串缓冲区,其初始容量为 16个字符。

publicStringBuffer(CharSequence seq)

构造一个字符串生成器,包含与指定的 CharSequence相同的字符。该字符串生成器的初始容量为 16加上 CharSequence参数的长度。

publicStringBuffer(String str)

构造一个字符串缓冲区,并将其内容初始化为指定的字符串内容。该字符串的初始容量为 16加上字符串参数的长度。

publicStringBuffer(int capacity)

构造一个不带字符,但具有指定初始容量的字符串缓冲区。

 

方法摘要

 

public StringBufferappend(char c)

将 char 参数的字符串表示形式追加到此序列。参数将被追加到此序列。此序列的长度将增加 1。

public StringBufferappend(char[] str)

将 char 数组参数的字符串表示形式追加到此序列。按顺序将数组参数中的字符追加到此序列的内容中。此字符将增加该参数的长度。

public StringBufferappend(String str)

将指定的字符串追加到此字符序列。按顺序追加 String 变量中的字符,使此序列增加该变量的长度。

StringBuffer buf = new StringBuffer();buf.append("Enter ");buf.append("your ");buf.append("name.");System.out.println(buf);buf.append("boolean = ").append(true);System.out.println(buf);

public StringBufferappend(StringBuffer sb)

将指定的 StringBuffer 追加到此序列中。按顺序将 StringBuffer 参数中的字符追加到此 StringBuffer 中,并使 StringBuffer 在长度上增加该参数的长度。如果 sb 为 null,则将 4 个 "null" 字符追加到此 StringBuffer 中。

StringBuffer buf = new StringBuffer();StringBuffer buf2 = new StringBuffer();buf.append("boolean = ").append(true);buf2.append(buf);System.out.println(buf2);

public intindexOf(String str)

返回第一次出现的指定子字符串在该字符串中的索引。

public int indexOf(String str, int fromIndex)

从指定的索引处开始,返回第一次出现的指定子字符串在该字符串中的索引。

public StringBufferinsert(int offset,String str)

将字符串插入此字符序列中。按顺序将 String 参数中的字符插入此序列中的指定位置,将该位置处原来的字符向后移,此序列将增加该参数的长度。

StringBuffer buf = new StringBuffer();buf.append(" Enter ");buf.append(" your ");buf.append(" name. ");buf.insert(10,"HHH");System.out.println(buf); // Enter  yoHHHur  name.

public StringBufferreverse()

将此字符序列用其反转形式取代。

String str = buf.reverse().toString();System.out.println(str);// .eman  ruHHHoy  retnE

public StringBufferreplace(int start, int end, String str)

使用给定 String中的字符替换此序列的子字符串中的字符。该子字符串从指定的 start处开始,一直到索引 end - 1处的字符,如果不存在这种字符,则一直到序列尾部。先将子字符串中的字符移除,然后将指定的 String插入 start

StringBuffer buf = new StringBuffer();buf.append(" Enter ");buf.append(" your ");buf.append(" name. ");buf.replace(0, 11, "StringBufferAPIDemo2");System.out.println(buf); //StringBufferAPIDemo2r  name.

public StringBufferdelete(int start, int end)

移除此序列的子字符串中的字符。该子字符串从指定的 start 处开始,一直到索引 end - 1 处的字符,如果不存在这种字符,则一直到序列尾部。如果 start 等于 end,则不发生任何更改。

buf.append("Enter ").append("your ").append("name.");buf.replace(0, 11, "StringBufferAPIDemo2");String str = buf.delete(6, 12).toString();System.out.println(str); //StringAPIDemo2name.

public Stringsubstring(int start, int end)

返回一个新的 String,它包含此序列当前所包含的字符子序列。该子字符串从指定的 start 处开始,一直到索引 end - 1 处的字符。

public StringtoString()

返回此序列中数据的字符串表示形式。分配一个新的 String 对象,并将它初始化,以包含当前由此对象表示的字符串序列。然后返回此 String。

注意:StringBufer支持的方法大部分与String类似。因为StringBuffer在开发中可以提升代码的性能,所以使用较多,这样为了保证用户操作的适应性,在StringBuffer类中定义的大部分方法名称都与String是一样的。

 

 

1.3 StringBuidler

 

StringBuilder类是非线程安全的可变字符序列。StringBuilder提供了一个人与StringBuffer兼容的API,但不保证同步。该类被设计用作StringBuffer的一个简易替换,用在字符串缓冲区被单个线程使用。如果可以,优先采用该类,因为在大多数实现中,它比StringBuffer要快。

 

 

2. Runtime类

 

1. Runtime类

在Java中Runtime类表示运行时操作类,是一个封装了JVM进程的类,每一个JVM都对应着一个Runtime类的实例,此实例由JVM运行时为其实例化。因为Runtime类本身的构造方法是私有的,如果想要取得一个Runtime实例,只能通过它的静态方法getRuntime()获得。 

 

2. 获得JVM内存空间的信息

使用Runtime类可以获得jvm中内存空间,包括最大内存空间、空闲内存空间等,可以回收垃圾,也可以终止当前所运行的jvm。

public long maxMemory()

返回 Java 虚拟机试图使用的最大内存量。

public long freeMemory()

返回 Java 虚拟机中的空闲内存量。

public void gc()

运行垃圾回收器。

//获得Runtime实例Runtime time = Runtime.getRuntime();//通过Runtime实例获得一些JVM信息//1.取得JVM中内存空间、空闲时间System.out.println("JVM最大内存量:"+time.maxMemory());System.out.println("JVM内存空闲量:"+time.freeMemory());//2.gc垃圾回收,释放空间String str = "Hello"+" World"+" Welcome"+" Beijing";for (int i = 0; i < 5000; i++) {str += i;}System.out.printf("%-20s = %g %s\n","操作String之后的,JVM空闲内存量",(double)(time.freeMemory()/1024)/1024,"MB");time.gc();System.out.printf("%-20s = %g %s\n","垃圾回收之后的,JVM空闲内存量",(double)(time.freeMemory()/1024)/1024,"MB");//3. 关闭JVMtime.exit(0);

 

3. Runtime类和Process类

除了可以观察jvm内存使用情况外,还可以用Runtime类直接调用本机的可执行程序,例如,可以调用本机的记事本程序,记事本的执行命令是“notepad.exe”。

//获得Runtime实例Runtime run = Runtime.getRuntime();try {//调用命令run.exec("notepad.exe");} catch (IOException e) {e.printStackTrace();}

在程序执行之后记事本程序会自动弹出来,当然也可以对程序进行进一步的控制,比如,在5s后让记事本关闭。此时就要用Process类,观察exec方法的返回值就是Process,表示一个操作系统的进程类。当记事本程序启动后,在系统中会增加一个进程,则可以通过Process对系统进行进行控制。

Runtime run = Runtime.getRuntime();Process pro = null;try {pro = run.exec("notepad.exe");} catch (IOException e) {e.printStackTrace();}// 睡眠5s之后关闭记事本程序try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}//结束进程pro.destroy();

 

 

3. System类

 

3.1. 概述

System 类是一个抽象类,所有的字段和方法都是静态的。其中包含一些有用的类字段和方法,它不能被实例化。在 System 类提供的设施中,有三个静态的变量in、out、err,分别对应标准输入、标准输出和错误输出流;有对外部定义的属性和环境变量的访问的方法;加载文件和库的方法;还有快速复制数组的一部分的实用方法。因此,System.in、System.out、System.err实际上表示三个对象,这也就是为什么可以用System.out.println("Hello World!")的原因。

3.2. API预览

public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)

从指定源数组中复制一个数组,复制从指定的位置开始,到目标数组的指定位置结束。

参数:

src - 源数组。

srcPos - 源数组中的起始位置。

dest - 目标数组。

destPos - 目标数据中的起始位置。

length - 要复制的数组元素的数量。

public static long currentTimeMillis()

返回以毫秒为单位的当前时间。注意,当返回值的时间单位是毫秒时,值的粒度取决于底层操作系统,并且粒度可能更大。当前时间与协调世界时 1970 年 1 月 1 日午夜之间的时间差。

public static void setProperties(Properties props)

将系统属性设置为 Properties 参数。

public static StringgetProperty(String key)

获取指定键指示的系统属性。

public static StringgetProperty(String key,String def)

获取用指定键描述的系统属性。

public static void gc()

运行垃圾回收器。

public static void exit(int status)

终止当前正在运行的 Java 虚拟机。参数用作状态码;根据惯例,非 0 的状态码表示异常终止。

 

 

3.3. 方法示例

//1.计算程序的执行时间long startTime = System.currentTimeMillis();int sum = 0;for (int i = 0; i < 300000001; i++) {sum += i;}long endTime = System.currentTimeMillis();System.out.println("所花费的时间:"+(endTime-startTime));//2. 获取本机的环境变量System.getProperties().list(System.out);//3. 列出指定属性System.out.println("系统版本为:"+System.getProperty("os.name")+System.getProperty("os.version")+System.getProperty("os.arch"));System.out.println("系统用户为:"+System.getProperty("user.name"));System.out.println("系统用户目录为:"+System.getProperty("user.home"));System.out.println("系统用户工作目录为:"+System.getProperty("user.dir"));

 

 

3.4 垃圾对象的回收

在Java中有垃圾的自动收集机制,可以不定期地释放Java中的垃圾空间,而且在前面讲Runtime类时也已经了解了如何进行垃圾的释放。在System类中也有一个gc()方法,此方法也可以进行垃圾的收集,而且此方法实际上是对Runtime类中的gc()方法的封装,功能与其相似。

publicstaticvoidgc() {

   Runtime.getRuntime().gc();

}

一个对象如果不被任何栈内存所引用,那么此对象就可以成为垃圾对象,等待被回收。实际上,等待的时间不确定的,所以可以直接调用System,gc()方法进行垃圾的回收。在实际的开发中,垃圾内存的释放基本上都是由系统自动完成的,除非特殊的情况,一般都很少直接去调用gc()方法。

如果我们想在垃圾回收之前干点什么事的话,java提供的对象终止化机制finalization)。在Object类里面有个finalize方法,其设计的初衷是在一个对象被真正回收之前,可以用来执行一些清理的工作。,示例如下:

class Demo {    private String codeType;    public Demo(){    }    //...setter() and getter()   public void finalize() {       System.out.println("gc --- > run");   }}public class FinalizeDemo{    public static void main(String args[]){                /*值得注意的是匿名对象很多         * 时候都是垃圾对象,但是还要注         * 意的是,即便如此,垃圾内存的释         * 放是由JVM自动释放的,没什么特殊         * 的情况是不会调用gc的         */        Demo demo = new Demo();            demo = null ;            //断开引用        System.gc();              //调用gc垃圾回收,强制性的      }}

在上面程序中强制调用了释放空间的方法,而且在对象被释放前调用了finalize()方法,如果在finalize()方法中出现了异常,则程序并不会受其影响,会继续执行。

 

3.5 对象的生命周期

对象生命周期示意图:

 

 

一个类加载后进行初始化,然后就可以进行对象的实例化,对象实例化时会调用构造方法完成,当一个对象不再使用时就要等待垃圾回收,然后对象终结,最终被程序卸载。

 

 

4. Locale类

 

4.1 国际化

 

国际化操作是在开发中较为常见的一种要求,实际上国际化的操作就是指一个程序可以同时适应多门语言,也就是说可以通过国际化操作让一个程序适应各个国家的语言要求。

当然,要想实现国际化程序只靠Locale类是不够的还需要属性文件和ResourceBundle类的支持,所谓的属性文件是指后缀为.properties的文件,文件中的内容保存结构为“key—value”形式。因为国家化的程序只显示语言的不同,那么就可以根据不同的国家定义不同的属性文件,属性文件中保存真正要使用的文字信息,要访问这些属性文件,可以使用ResourceBundle类来完成。

如果要实现Java程序的国际化操作必须通过以下3个类完成:

java.util.Locale

java.util.ResourceBundle

java.text.MessageFormat

这3个类的具体操作流程为通过Local类所指定的区域码,然后ResourceBundle根据Local类所指定的区域码找到相应的资源文件,如果资源文件中存在动态文本,则使用MessageFormat进行格式化。

注意:资源文件有时也称为属性文件,可以直接使用Java类集中提供的Properties类进行操作。

4.2 Locale类

Locale类是实现国际化的一个重要类,下面是Locale类的构造方法:

 

构造方法摘要

Locale(String language) 
          
根据语言代码构造一个语言环境。

 

Locale(String language, String country) 
          
根据语言和国家/地区构造一个语言环境。

 

Locale(String language, String country, String variant) 
          
根据语言、国家/地区和变量构造一个语言环境。

 

实际上对于各个国家都有对应的ISO编码,例如,中国的编码zh-CN,英语-美国的编码为en-US,法语的编码fr-FR。语言参数是一个有效的 ISO 语言代码。这些代码是由 ISO-639 定义的小写两字母代码。在许多网站上都可以找到这些代码的完整列表,如:
http://www.loc.gov/standards/iso639-2/englangn.html国家/地区参数是一个有效的 ISO 国家/地区代码。这些代码是由 ISO-3166 定义的大写两字母代码。在许多网站上都可以找到这些代码的完整列表,如:
http://www.iso.ch/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/list-en1.html

 

4.3 ResourceBundle类

 

ResourceBundle类主要作用是读取属性文件,读取属性文件时可以直接指定属性文件的名称(指定名称时不需要文件的后缀),也可以根据Locale所指定的区域码来选取指定的资源文件,ResourceBundle类的常用方如下:

public static final ResourceBundlegetBundle(String baseName)

使用指定的基本名称、默认的语言环境和调用者的类加载器获取资源包。调用此方法等同于调用getBundle(baseName, Locale.getDefault(), this.getClass().getClassLoader())。

public static final ResourceBundlegetBundle(String baseName,Locale locale)

使用指定的基本名称、语言环境和调用者的类加载器获取资源包。

参数:

baseName - 资源包的基本名称,是一个完全限定类名

locale - 资源包所需的语言环境

public final StringgetString(String key)

从此资源包或它的某个父包中获取给定键的字符串。调用此方法等同于调用

(String) getObject(key)。

public abstract Enumeration<String>getKeys()

返回键的枚举。

public Set<String>keySet()

返回此 ResourceBundle 及其父包中包含的所有键的 Set。

protected Set<String>handleKeySet()

返回 包含在此 ResourceBundle 中的键的 Set。

如果现在要使用ResourceBunlde对象,则直接通过ResourceBundle类中的静态方法getBundle()取得。

示例1,取得资源文件中的内容

资源文件Message.properties:

info = HELLOResourceBundle bundle = ResourceBundle.getBundle("Message");//定位资源文件String valueString = bundle.getString("info");//取得资源内容System.out.println(valueString);

 

4.4 国际化实现

根据Locale所选择的国家不同,输出不同国家的“你好!”。

中文:你好!

英语:Hello!

法语:Bonjour!

首先根据不同国家的代码建立不同的属性文件,建立的属性文件与class文件保存在同一个文件夹中。因为现在程序要使用的有3种语言,所以要定义3中属性文件,在属性文件定义时必须按照“名称_国家代码”的形式命名,即所有相关的属性文件名称全部一样,只有国家代码不一样,如下:

1). 中文属性文件:Message_zh_CN.properties

info = \u4f60\u597d\uff01

实际上\u4f60\u597d\uff01表示的是ASCII码,就是中文“你好!”,在属性文件的操作中是不能直接写入中文的,就算写入中文,在读取出来的也是乱码,因此必须将相应的中文变为Unicode编码才行,要成功地将一个中文编码变为Unicode编码,可以直接使用jdk自带的“native2ascii”命令,输入相应的中文后会自动将其进行编码。

C:\code>native2ascii < words.txt

\u4f60\u597d\uff01

2). 英语的属性文件:Message_en_US.properties

info=Hello!

3). 法语的属性文件:Message_fr_FR.properties

info=Bonjour!

Locale zh = new Locale("zh", "CN");//表示中国地区Locale en = new Locale("en", "US");//表示美国地区Locale fr = new Locale("fr", "FR");//表示法国地区ResourceBundle zhBundle = ResourceBundle.getBundle("Message",zh);//定位中文资源文件ResourceBundle enBundle = ResourceBundle.getBundle("Message",en);//定位英语资源文件ResourceBundle frBundle = ResourceBundle.getBundle("Message",fr);//定位法语资源文件System.out.println("中文:"+zhBundle.getString("info"));//取得资源内容System.out.println("英语:"+enBundle.getString("info"));System.out.println("法语:"+frBundle.getString("info"));

 

4.5. 处理动态文本

在上面程序中,所有资源内容都是固定的,但是输出的信息中如果包含了动态文本,则必须使用占位符清楚地表示出动态文本的位置,占位符使用”{编号}”的格式出现。使用占位符之后,程序可以直接通过MessageFormat对信息进行格式化,为占位符动态设置文本内容。

MessageFormatFormat类的子类,Format类主要实现格式化操作,除了MessageFormat子类外,Format还有NumberFormatDateFormat两个子类,这两个子类的使用在后面说到,先来看MessageFormat如何使用。

注意:在进行国际化操作时,不只是只有文字需要处理,实际上数字的显示、日期的显示都要符合各个区域的要求。可以通过本地计算机的“区域和语言选项”查看到这一点。

在这里要同时改变的有数字、货币、时间等,所以Format类提供了3个子类,即MessageFormatDateFormatNumberFormat

例如,现在要输出的信息(以中文为例)是“你好,xxx!”,其中,xxx的内容是由程序动态设置的,所以,此时修改之前的3个属性文件,让其动态地接受程序的3个文本,

1).中文的属性文件: Message_zh_CN.properties

\u4f60\u597d\uff0c{0}\uff01

2).英语的属性文件:Message_en_US.properties

info=Hello,{0}!

3). 法语的属性文件:Message_fr_FR.properties

info=Bonjour,{0}!

在以上3个属性文件中,都加入了“{0}”,表示一个占位符,如果有更多的占位符,则直接在后面继续加上“{1}”“{2}”即可。继续使用之前的Locale类和ResourceBundle类读取资源文件的内容,但是读取之后的文件因为要处理占位符的内容,所以要使用MessageFormat类进行处理。

public static Stringformat(String pattern,Object... arguments)

创建具有给定模式的 MessageFormat,并用它来格式化给定的参数。这等效于

(new MessageFormat(pattern)).format(arguments, new StringBuffer(), null).toString()。

参数:

pattern – 要匹配的字符串

arguments – 输入参数可以任意多个,没有个数限制

Locale zh = new Locale("zh", "CN");// 表示中国地区Locale en = new Locale("en", "US");// 表示美国地区Locale fr = new Locale("fr", "FR");// 表示法国地区ResourceBundle zhBundle = ResourceBundle.getBundle("Message", zh);// 定位中文资源文件ResourceBundle enBundle = ResourceBundle.getBundle("Message", en);// 定位英语资源文件ResourceBundle frBundle = ResourceBundle.getBundle("Message", fr);// 定位法语资源文件System.out.println("中文:" + MessageFormat.format(zhBundle.getString("info"), "张三"));// 取得资源内容System.out.println("英语:" + MessageFormat.format(enBundle.getString("info"), "zhangsan"));System.out.println("法语:" +  MessageFormat.format(frBundle.getString("info"), "zhangsan"));

程序运行结果:

中文:你好,张三!英语:HELLO,zhangsan!法语:Bonjour,zhangsan!

 

5. Date类

 

5.1 Date类

在程序开发中经常会遇到日期类型的操作,在Java中对于日期的操作提供了很好的支持,主要使用java.util包中的Date、Calendar以及java.text包中的SimpleDateFormat。

Date类是一个较为简单的操作类,在使用中直接使用java.util.Date类的构造方法进行输出就可以得到一个完整的日期。

public Date()

分配 Date 对象并初始化此对象,以表示分配它的时间(精确到毫秒)。

Date date = new Date();System.out.println("当前的日期:"+date);

//当前的日期:Mon Nov 25 11:51:56 CST 2012

从程序的运行结果看,已经得到了系统的当前日期,但是对于日期格式并不符合平常看到的格式,而且现在的时间也不能准确地精确到毫秒,所以要使用用户自定义格式来显示时间,可以使用Calendar类完成操作。

 

5.2 Calendar类

Calendar类可以将取得的时间精确到毫秒。但是,这个类本身是一个抽象类,所以只能通过Calendar的子类GregorianCalendar类进行实例化。在Calendar中提供了部分常量,分别表示日期的各个数字。

public static final intYEAR

指示年的 get  set 的字段数字。这是一个特定于日历的值。

public static final intMONTH

指示月份的 get  set 的字段数字。这是一个特定于日历的值。在格里高利历和罗马儒略历中一年中的第一个月是 JANUARY,它为 0;最后一个月取决于一年中的月份数。

public static final intDAY_OF_MONTH

get  set 的字段数字,指示一个月中的某天。它与 DATE 是同义词。一个月中第一天的值为 1

public static final intDAY_OF_YEAR

get  set 的字段数字,指示当前年中的天数。一年中第一天的值为 1

public static final intHOUR

get  set 的字段数字,指示上午或下午的小时。HOUR 用于 12 小时制时钟 (0 - 11)。中午和午夜用 0表示,不用 12表示。例如,在 10:04:15.250 PM这一时刻,HOUR  10

public static final intHOUR_OF_DAY

get  set 的字段数字,指示一天中的小时。HOUR_OF_DAY 用于 24 小时制时钟。例如,在 10:04:15.250 PM这一时刻,HOUR_OF_DAY  22

public static final intMINUTE

get  set 的字段数字,指示一小时中的分钟。例如,在 10:04:15.250 PM 这一时刻,MINUTE  4

public static final intSECOND

get  set 的字段数字,指示一分钟中的秒。例如,在 10:04:15.250 PM 这一时刻,SECOND  15

public static final intMILLISECOND

get  set 的字段数字,指示一秒中的毫秒。例如,在 10:04:15.250 PM 这一时刻,MILLISECOND  250

Calendar类提供的方法:

public staticCalendargetInstance()

使用默认时区和语言环境获得一个日历。返回的 Calendar 基于当前时间,使用了默认时区和默认语言环境。

public booleanafter(Object when)

判断此 Calendar 表示的时间是否在指定 Object 表示的时间之后,返回判断结果。

public booleanbefore(Object when)

判断此 Calendar 表示的时间是否在指定 Object 表示的时间之前,返回判断结果。

public intget(int field)

返回给定日历字段的值。在 lenient模式下,所有日历字段都被标准化。在 non-lenient模式下,所有日历字段都是经过验证的,如果任何日历字段有超出范围的值,则此方法抛出一个异常。标准化和验证都是通过 complete() 方法处理的,这个过程与日历系统有关。

Calendar cale = new GregorianCalendar();System.out.printf("%d年%d月%d日%d时%d分%d秒%d毫秒", cale.get(Calendar.YEAR),cale.get(Calendar.MONTH) + 1, cale.get(Calendar.DAY_OF_MONTH),cale.get(Calendar.HOUR_OF_DAY), cale.get(Calendar.MINUTE),cale.get(Calendar.SECOND), cale.get(Calendar.MILLISECOND));

 

5.3 DateFormat类

按照上面的方式取得系统时间,代码比较复杂,所有Java中又提供了DateFormat类,可以很好地格式化表示时间。

DateFormat类与MessageFormat类都属于Format类的子类。DateFormat的定义如下:

public abstract classDateFormat

extendsFormat

DateFormat是日期/时间格式化子类的抽象类,它以与语言无关的方式格式化并解析日期或时间。日期/时间格式化子类(如 SimpleDateFormat)允许进行格式化(也就是日期 ->文本)、解析(文本->日期)和标准化。将日期表示为 Date 对象,或者表示为从 GMT(格林尼治标准时间)1970 1 1 00:00:00这一刻开始的毫秒数。

DateFormat类常用方法:

public static finalDateFormatgetDateInstance()

获取日期格式器,该格式器具有默认语言环境的默认格式化风格。

public static finalDateFormatgetDateInstance(int style,Locale aLocale)

获取日期格式器,该格式器具有给定语言环境的给定格式化风格。

参数:

style -给定的格式化风格。例如,SHORT用于 US 语言环境中的 "M/d/yy"

aLocale -给定的语言环境。

public static finalDateFormatgetDateTimeInstance()

获取日期/时间格式器,该格式器具有默认语言环境的默认格式化风格。

public static finalDateFormatgetDateTimeInstance(int dateStyle, int timeStyle)

获取日期/时间格式器,该格式器具有默认语言环境的给定日期和时间格式化风格。

参数:

dateStyle -给定的日期格式化风格。例如,SHORT用于 US 语言环境中的 "M/d/yy"

timeStyle -给定的时间格式化风格。例如,SHORT用于 US 语言环境中的 "h:mm a"

DateFormat date1 = DateFormat.getDateInstance(); //取得日期DateFormat time1 = DateFormat.getDateTimeInstance();//取得日期时间System.out.printf("Date -> %s\nDateTime -> %s\n", date1.format(new Date()),time1.format(new Date()));

程序运行结果:

Date -> 2012-11-25DateTime -> 2012-11-25 23:45:10

 

从程序运行结果中可以看到,第2DateTime显示了时间,但还不是比较合理的中文显示格式。如果想要取得更加合理的时间,则必须在构造DateFormat对象时传递格式化风格,下面是指定日期格式化风格的示例。

/* 指定日期时间格式化风格*///取得日期,并设置日期显示风格date1 = DateFormat.getDateInstance(DateFormat.YEAR_FIELD, new Locale("zh", "CN"));//取得日期、时间,并设置日期、时间显示风格time1 = DateFormat.getDateTimeInstance(DateFormat.YEAR_FIELD,DateFormat.ERA_FIELD, new Locale("zh", "CN"));System.out.printf("Date -> %s\nDateTime -> %s\n",date1.format(new Date()), time1.format(new Date()));

 

程序运行结果:

Date -> 2012年11月25日DateTime -> 2012年11月25日 下午11时58分05秒 CST

 

 

5.4 SimpleDateFormat类

在项目开发中,会经常将一个日期格式转换为另一种日期格式,例如,原日期为2012-11-25 23:45:10,转换后的日期为20121125下午114510.从这两个日期可以知道,日期的数字完全一样,只是日期的格式有所不同,要想实现转换就必须使用SimpleDateFormat类完成。首先定义出一个完整的日期转换模板,在模板中通过特定的日期标记可以将一个日期格式中的日期数字提取出来,日期格式模板如下:

SimpleDateFormat类中的常用方法:

public SimpleDateFormat(String pattern)

用给定的模式和默认语言环境的日期格式符号构造 SimpleDateFormat。注:此构造方法可能不支持所有语言环境。要覆盖所有语言环境,请使用 DateFormat 类中的工厂方法。

public Dateparse(String text,ParsePosition pos)

解析字符串的文本,生成 Date。

public finalStringformat(Date date)

将一个 Date 格式化为日期/时间字符串。

//定义日期时间的字符串String strDate = "2010-10-20 10:11:30.345";//准备第1个模板,从字符串中提取日期数字String part1 = "yyyy-MM-dd HH:mm:ss.SSS";//准备第2个模板,将提取后的日期数字变为指定的格式String part2 = "yyyy年MM月dd日 HH时mm分ss秒SSS毫秒";SimpleDateFormat sdf1 = new SimpleDateFormat(part1);SimpleDateFormat sdf2 = new SimpleDateFormat(part2);Date d = null;try {d = sdf1.parse(strDate);//将给定字符串中的日期取出来} catch (ParseException e) {e.printStackTrace();}System.out.println(sdf2.format(d));//将日期变为新的格式

//20101020 101130345毫秒

在程序中,首先使用第1个模板将字符串中表示日期数字取出,然后使用第2个模板将这些日期数字重新转换为新的格式表示。

在实际的开发中,用户所输入的各个数据都是以String的方式进行接收的,所以此时为了可以正确的将String变为Date型数据,可以依靠SimpleDateFormat类完成。

//定义日期时间的字符串String strDate = "2010-10-20 10:11:30.345";String part = "yyyy-MM-dd HH:mm:ss.SSS";SimpleDateFormat sdf = new SimpleDateFormat(part);//将给定字符串中日期提取出来Date d  = sdf.parse(strDate);System.out.println(d);

程序输出结果:

Wed Oct 20 10:11:30 CST 2010

 

实例操作——取得完整日期

1).实现基于Calendar

public class DateTime1 {private Calendar calendar = null;public DateTime1() {this.calendar = new GregorianCalendar();}/* * 取得完整的日期,格式为:yyyy-MM-dd HH:mm:ss.SSS */public String getDate(){StringBuffer buffer = new StringBuffer();buffer.append(calendar.get(Calendar.YEAR)).append("-");buffer.append(this.addZero(calendar.get(Calendar.MONTH)+1, 2)).append("-");buffer.append(this.addZero(calendar.get(Calendar.DAY_OF_MONTH), 2)).append(" ");buffer.append(this.addZero(calendar.get(Calendar.HOUR_OF_DAY), 2)).append(":");buffer.append(this.addZero(calendar.get(Calendar.MINUTE), 2)).append(":");buffer.append(this.addZero(calendar.get(Calendar.SECOND), 2)).append(".");buffer.append(this.addZero(calendar.get(Calendar.MILLISECOND), 3));return buffer.toString();}/* * 得到完整的日期,格式为:yyyy年MM月dd日 HH时mm分ss秒SSS毫秒 */public String getDateTime(){StringBuffer buffer = new StringBuffer();buffer.append(calendar.get(Calendar.YEAR)).append("年");buffer.append(this.addZero(calendar.get(Calendar.MONTH)+1, 2)).append("月");buffer.append(this.addZero(calendar.get(Calendar.DAY_OF_MONTH), 2)).append("日");buffer.append(this.addZero(calendar.get(Calendar.HOUR), 2)).append("时");buffer.append(this.addZero(calendar.get(Calendar.MINUTE), 2)).append("分");buffer.append(this.addZero(calendar.get(Calendar.SECOND), 2)).append("秒");buffer.append(this.addZero(calendar.get(Calendar.MILLISECOND), 3)).append("毫秒");return buffer.toString();}/* * 得到时间戳:yyyyMMddHHmmssSSS */public String getTimeStamp(){StringBuffer buffer =  new StringBuffer();buffer.append(calendar.get(Calendar.YEAR));buffer.append(this.addZero(calendar.get(Calendar.MONTH)+1, 2));buffer.append(this.addZero(calendar.get(Calendar.DAY_OF_MONTH), 2));buffer.append(this.addZero(calendar.get(Calendar.HOUR), 2));buffer.append(this.addZero(calendar.get(Calendar.MINUTE), 2));buffer.append(this.addZero(calendar.get(Calendar.SECOND), 2));buffer.append(this.addZero(calendar.get(Calendar.MILLISECOND), 3));return buffer.toString();}/* * 考虑到日期中有前导0,(9月--09)所以加上补零的方法 */private String addZero(int num,int len){StringBuffer  s = new StringBuffer();s.append(num);while (s.length() < len) { //如果长度不足,则继续补0s.insert(0, "0");      //在第1个位置处补0}return s.toString();}public static void main(String[] args) {DateTime1 time1 = new DateTime1();System.out.println("系统日期:"+time1.getDate());System.out.println("中文日期:"+time1.getDateTime());System.out.println("时间戳:"+time1.getTimeStamp());}}


 

2).基于SimpleDateFormat类实现

使用SimpleDateFormat类可以方便地把一个日期变为指定格式,所以直接使用此类操作最简单、最合适的。

public class DateTime2 {private SimpleDateFormat sdf =  null;public String getDate(){this.sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");return this.sdf.format(new Date());}public String getDateComplete(){this.sdf = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒SSS毫秒");return this.sdf.format(new Date());}public String getTimeStamp(){this.sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");return this.sdf.format(new Date());}public static void main(String[] args) {DateTime2 time1 = new DateTime2();System.out.println("系统日期:"+time1.getDate());System.out.println("中文日期:"+time1.getDateComplete());System.out.println("时间戳:"+time1.getTimeStamp());}}


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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



原创粉丝点击