在实际的项目开发中,经常借助于一些类来帮助完成特定的功能,例如进行数学运算、字符串运算、日期运算等等,这些类由Sun公司提供,放在Java 2 Platform软件包内,不需要用户再次编写而直接使用,我们称这些类叫“Java工具类”,这里将会学习这些工具类的部分内容,在将来的项目中我们就可以通过它们的帮助,来完成很多特定的任务,达到快速开发的目的。所有这些类的详细信息均可以通过查询API规范获得。
1 概述
在基础库部分,Sun公司提供了极其丰富的功能类,为了便于区分,根据类的功能大致把这些类放在了不同的包内,例如java.lang包、java.util包、java.io包、java.sql包、java.text包等等。这里主要讲解java.lang包及java.text包中的部分类,对于其他的三个包,将会在后续单独讲解。
对于初学者来说,最为常用的工具类有封装类、String、StringBuffer、Random、Date、Calendar、SimpleDateFormat及Math静态类等等;但是,Java学习之路漫长也曲折,Sun公司提供的支持类成千上万,很难一次掌握,即便是本章内容,也拥有众多类和方法的介绍,在后续的学习、工作过程中,也会遇到自己不会甚至没有见过的新类,你会发现,这众多的类和方法之间,其实充满了联系与区别,是有规律可循的,类的名字、方法的名字,也非常便于记忆。只要各位从容面对,勤加练习,善于归纳总结,多多翻阅JDK API帮助文档,那么学好这部分内容是不困难的。
2包装类
我们知道,java中的基本数据类型是在堆栈上创建的,而所有的对象类型都是在堆上创建的(对象的引用在堆栈上创建)。比如String s=new String(“good luck!”); 其中new String()是在堆上创建的,而它的引用String s是在堆栈上。
很显然,栈内存上的数据比堆内存上的数据速度要快很多,不过,虽然在堆栈上分配内存效率高,不过在堆栈上分配内存有内存泄露的问题,而这并不是任意一个程序员都能解决的问题。并且,对于基本数据类型来说,早在一学期我们就知道它是按值传递的。所以,如果各位想把一个基本数据类型的数据按引用传递,那么是办不到的。包装类(Wrapper Class)的出现,正是为了解决这个问题,包装类把基本数据类型的数据封装为引用类型的对象,而且提供了很多有用的方法。
对于Java的基本数据类型,Sun公司均提供了对应的包装类,如下表所示,各位可以通过查阅API文档来获得这些包装类的详细信息。值得注意的是,所有的包装类均位于java.lang包下,而这个包会由JVM编译器在编译时自动导入我们的程序,所以可以不用手工导入该包下的类而直接使用。
基本数据类型 | 对应包装类 |
boolean | Boolean |
byte | Byte |
short | Short |
int | Integer |
long | Long |
char | Character |
float | Float |
double | Double |
大多包装类均具有如下方法:
·带有基本值参数并创建包装类对象的构造方法,如可以利用Integer包装类创建对象,Integer obj=new Integer(145) 1aD>Zn
·带有字符串参数并创建包装类对象的构造方法,如new Integer("-45.36") A =:(IcM#
d9G{S9X
·生成字符串表示法的toString()方法,如obj.toString()
·:%^D,MGi ·· 对同一个类的两个对象进行比较的equals()方法,如obj1.eauqls(obj2) 6=Hxw$6u0U
·生成哈稀表代码的hashCode方法,如obj.hasCode() w_+c$E i+b ?Zt
·将字符串转换为基本值的 parseType方法,如Integer.parseInt(args[0]) (i' a 4
·可生成对象基本值的typeValue方法,如obj.intValue()
下以int基本类型的包装类Integer和Character为例,带领各位了解包装类。
3 Integer整数类
Integer是int基本类型的包装类,下面我们一起来看看Integer类有哪些特点,从介绍封装类的属性、构造器和方法展开。
3.1 属性
属性名称 | 描述 |
static int MAX_VALUE | 返回最大的整型数 |
static int MIN_VALUE | 返回最小的整型数 |
static Class TYPE | 返回当前类型 |
示例:
System.out.println("Integer.MAX_VALUE:"+Integer.MAX_VALUE); 输出结果为:Integer.MAX_VALUE:2147483647 |
3.2 构造方法
构造器 | 描述 |
Integer(int value) | 通过一个int的类型构造对象 |
Integer(String s) | 通过一个String的类型构造对象 |
注:本书对类的构造方法、方法的列表如无特殊说明,均指public方法。
示例:
//生成了一个值为1234的Integer对象
Integer i = new Integer(1234);
Integer i = new Integer("1234");
|
3.3 方法介绍
说明:
1. 所有方法均为public
2. 书写格式:[修饰符] <返回类型> <方法名([参数列表])>
方法名称 | 描述 |
byteValue() | 取得用byte类型表示的整数 |
int compareTo(Integer anotherInteger) | 比较两个整数。相等时返回0;小于时返回负数;大于时返回正数 |
int compareTo(Object o) | 将该整数与其他类进行比较。其中o必须为Integer类实例,否则,抛出ClassCastException异常 |
static Integer decode(String nm) | 将字符串转换为整数 |
double doubleValue() | 取得该整数的双精度表示 |
boolean equals(Object obj) | 比较两个对象 |
float floatValue() | 取得该整数的浮点数表示 |
static Integer getInteger(String nm) | 根据指定名确定系统特征值 |
int hashCode() | 返回该整数类型的哈希表码 |
int intValue() | 返回该整型数所表示的整数 |
long longValue() | 返回该整型数所表示的长整数 |
static int parseInt(String s) | 将字符串转换成整数。 s必须是十进制数组成,否则抛出NumberFormatException异常 |
static int parseInt(String s, int radix) | 以radix为基数radix返回s的十进制数。所谓的基数,就是“几进制” |
short shortValue() | 返回该整型数所表示的短整数 |
static String toBinaryString(int i) | 将整数转为二进制数的字符串 |
static String toHexString(int i) | 将整数转为十六进制数的字符串 |
static String toOctalString(int i) | 将整数转为八进制数的字符串 |
String toString() | 将该整数类型转换为字符串 |
static String toString(int i) | 将该整数类型转换为字符串。不同的是,此为类方法 |
static String toString(int i, int radix) | 将整数i以基数radix的形式转换成字符串 |
static Integer valueOf(String s) | 将字符串转换成整数类型 |
static Integer valueOf(String s, int radix) | 将字符串以基数radix的要求转换成整数类型 |
以下示例使用了compareTo方法对两个Integer对象进行大小比较,比较的内容为Integer对象对应的int值,根据大小相等的不同,返回结果分别为大于、小于、等于0的数字:
Integer i = new Integer(1234);
System.out.println("i.compareTo: " + i.compareTo(new Integer(123)));
//输出结果为:i.compareTo: 1
|
以下示例返回一个整数的16进制形式字符串:
int i = 54321;
System.out.println("Integer.toString(int i, int radix): " + Integer.toString(i,16));
//结果为:Integer.toString(int i, int radix): d431
|
4 Character字符类
Character 类在对象中包装一个基本类型 char 的值。Character 类型的对象包含类型为 char 的单个字段。
此外,该类提供了几种方法,以确定字符的类别(小写字母,数字,等等),并将字符从大写转换成小写,反之亦然。
4.1 属性
属性名称 | 属性描述 |
static char MIN_VALUE | 此字段的常量值是 char 类型的最小值,即 '\u0000' |
static char MAX_VALUE | 此字段的常量值是 char 类型的最大值,即 '\uFFFF' |
static Class TYPE | 表示基本类型 char 的 Class 实例 |
4.2 构造方法
Character(char value):以char参数构造一个Character对象
4.3 方法
说明:
1. 所有方法均为public;
2. 书写格式:[修饰符]<返回类型> <方法名([参数列表])>
具体方法请查看API文档
示例:
package com.lesson4;
/**
* Character包装类的用法
*/
public class CharacterDemo {
public static void main(String[] args) {
Character ch1 = new Character('a');
Character ch2 = new Character('A');
// ch1的char值
System.out.println("char value of ch1 : "
// 对比ch1和ch2的大小
System.out.println("ch1 compare to ch2 : "
// 表示范围的最小值
System.out.println("min value(int) : " + (int) Character.MIN_VALUE);
// 表示范围的最大值
System.out.println("max value(int) : " + (int) Character.MAX_VALUE);
// 判断一个字符是否是数字形式
System.out.println("is digit '1' : " + Character.isDigit('1'));
// 判断一个字符是否是大写形式
System.out.println("is upper case 'a' : " + Character.isUpperCase('a'));
// 判断一个字符是否是空格
System.out.println("is space char ' ' : " + Character.isSpaceChar(' '));
// 判断一个字符是否是字母
System.out.println("is letter '1' :" + Character.isLetter('1'));
// 判断一个字符是否是字母或数字
System.out.println("is letter or digit '好' :"
+ Character.isLetterOrDigit('好'));
// 把字母转化为大写形式
System.out.println("to upper case 'a' :" + Character.toUpperCase('a'));
}
}
|
运行后结果如下:
5 String字符串类
字符串大量用于我们的程序中,Java提供了String类专门用于表示字符串,内有大量实用的方法,大家要牢牢掌握。
5.1 构造方法
构造器 | 描述 |
String() | 构造一个空字符串对象 |
String(byte[] bytes) | 通过byte数组构造字符串对象 |
String(char[] chars) | 通过字符数组构造字符串对象 |
String(String original) | 构造一个original的副本,即拷贝一个original |
String(StringBuffer buffer) | 通过StringBuffer数组构造字符串对象 |
示例演示String类构造方法的使用:
byte[] b = {'a','b','c','d','e','f','g','h','i','j'};
char[] c = {'0','1','2','3','4','5','6','7','8','9'};
String sb = new String(b);
String sb_sub = new String(b,3,2);
String sc = new String(c);
String sc_sub = new String(c,3,2);
String sb_copy = new String(sb);
System.out.println("sb: "
System.out.println("sb_sub: "
System.out.println("sc: "
System.out.println("sc_sub: "
System.out.println("sb_copy: "
输出结果为:
sb: abcdefghij
sb_sub: de
sc: 0123456789
sc_sub: 34
sb_copy: abcdefghij
|
5.2 方法
示例
String s = new String("abcdefghijklmnopqrstuvwxyz");
System.out.println("s.charAt(5): "
本例从字符串中提取字符,运行结果为:s.charAt(5): f
|
示例:
String s1 = new String("abcdefghijklmn");
String s2 = new String("abcdefghij");
String s3 = new String("abcdefghijalmn");
System.out.println("s1.compareTo(s2): " + s1.compareTo(s2) ); System.out.println("s1.compareTo(s3): "
本例对两个字符串进行对比,运行结果为:
s1.compareTo(s2): 4
s1.compareTo(s3): 10
|
示例:
String s1 = new String("abcdefghij");
String s2 = new String("ghij");
System.out.println("s1.endsWith(s2): "
本例判断一个字符串是否是另外一个字符串的结尾,运行结果为:s1.endsWith(s2): true
|
示例:
char[] s1 = {'I',' ','l','o','v','e',' ','h','e','r','!'};
String s2 = new String("you!");
s2.getChars(0,3,s1,7); //s1=I love you!
System.out.println( s1 );
运行结果为:I love you!
|
示例:
String s = new String("write once, run anywhere!");
String ss = new String("run");
System.out.println("s.indexOf('r'): " + s.indexOf('r') );
System.out.println("s.indexOf('r',2): " + s.indexOf('r',2) );
System.out.println("s.indexOf(ss): "
本例在一个字符串中查找某段字符串的位置,注意indexOf方法的不同形式,运行结果为:
s.indexOf('r'): 1
s.indexOf('r',2): 12
s.indexOf(ss): 12
|
示例:
String s = new String ("write once, run anywhere!");
String ss = new String("write");
String sss = new String("once");
System.out.println("s.startsWith(ss): "
System.out.println("s.startsWith(sss,6): "
本例判断一个字符串是否是另外一个字符串的开始,运行结果为:
s.startsWith(ss): true
s.startsWith(sss,6): true
|
示例:
String s = new String("java.lang.Class String");
System.out.println("s.toUpperCase(): "
System.out.println("s.toLowerCase(): "
本例把一个字符串转换为对应的大写、小写形式,运行结果为:
s.toUpperCase(): JAVA.LANG.CLASS STRING
s.toLowerCase(): java.lang.class string
|
字符串与字符数组关系密切,而且它们可以互相转换,通过String构造方法可以将一个字符数组构造为一个字符串,而通过String类的toCharArray()方法也可以将一个字符串转换为字符数组。其实,通过查看String类的源代码可以知道(多看源码长见识),String类的本质就是由字符数组构建的,String类的第一行就定义到:
/** The value is used for character storage. */
private final char value[];
|
这个值数组是private final类型的,这也说明一个问题,那就是一旦这个数组被赋值,那么它就不能再被修改了,到底是不是这样呢?请看下一节。
5.3 字符串的不变性
首先来看一个示例,示例中使用String类的concat()方法,试图将第二个字符串连接在第一个字符串的后面,使用replace()方法,试图将字符串中的某些字符替换掉。
示例:
package com.lesson4;
/**
* String类的字符串不变性
*/
public class StringDemo {
public static void main(String[] args) {
String s1 = new String("hello ");
//将svse连接在s1的后面
s1.concat("abc");
System.out.println("s1 = "
// 使用replace方法把字符串s2中的字符o替换为u
String s2 = new String("good morning!");
s2.replace('o', 'u');
System.out.println("s2 = "
}
}
|
运行程序,查看结果如下:
可以看到字符串s1、s2虽然尝试进行了修改,但是,它们并没有发生任何变化,这是为什么呢?其实,一个字符串对象一但创建,那么这个字符串对象内容存放地址里面的内容就不能改变,对于s1来说,我们尝试在其后连接上abc,因不能对s1进行直接修改,所以将会创建一个新的字符串对象,而新创建的对象的引用,我们并未将其赋给s1,结果导致s1的值没有变化。对于s2来说,也是一样的道理。
那么如何解决这个问题呢?很简单,把新的字符串的引用,赋给s1、s3即可。
//其余部分省略
s1 = s1.concat("abc");
s2 = s2.replace('o', 'u');
|
由于在对String字符串进行修改的过程中,将会创建新的字符串对象,如果因为需要而反复修改字符串,将大大浪费系统资源,创建一大堆无用的对象。为了避免这种情况出现,我们需要能直接修改的字符串对象,这就是StringBuffer。
6 StringBuffer字符串缓冲类
在实际应用中,经常会遇到对字符串进行动态修改。这时候,String类的功能受到限制,而StringBuffer类可以完成字符串的动态添加、插入和替换等操作(注意有些中文API上说的是“不能修改”,是误译,英文原版为“can be modified”),对StringBuffer的修改,是直接的,不会创建多余的对象。
4.6.1 构造方法
构造器名称 | 描述 |
StringBuffer() | 构造一个没有任何字符的StringBuffer类 |
StringBuffer(int length) | 构造一个没有任何字符的StringBuffer类,并且,其长度为length |
StringBuffer(String str) | 以str为初始值构造一个StringBuffer类 |
6.2 方法
以下示例演示了对StringBuffer对象进行字符串追加和插入操作。StringBuffer 上的主要操作是 append 和 insert 方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串缓冲区中。append 方法始终将这些字符添加到缓冲区的末端;而 insert 方法则在指定的点添加字符。
package com.lesson4;
/**
* StringBuffer,带有缓冲区的字符串
*/
public class StringBufferDemo {
public static void main(String[] args) {
String question = new String("1+1=");
int answer = 3;
boolean result = (1 + 1 == 3);
StringBuffer sb = new StringBuffer();
sb.append(question);
sb.append(answer);
sb.append(result);
sb.insert(5, ',');
System.out.println(sb);
}
}
结果为:
1+1=3,false
|
以下示例调整了StringBuffer的容量,这将会给StringBuffer对象分配更多的空间。其实,如果容量不够,那么编译器将会自动分配更高的容量。
package com.lesson4;
/**
* 调整StringBuffer对象的容量
*/
public class StringBufferDemo {
public static void main(String[] args) {
StringBuffer sb1 = new StringBuffer(5);
StringBuffer sb2 = new StringBuffer(5);
sb1.ensureCapacity(6);
sb2.ensureCapacity(100);
System.out.println( "sb1.Capacity: "
System.out.println( "sb2.Capacity: "
}
}
结果为:
sb1.Capacity: 12
sb2.Capacity: 100
|
以下示例演示了将字符数组复制到字符串:
package com.lesson4;
/**
*把字符数组放入StringBuffer
*/
public class StringBufferDemo {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("I love her!");
char[] i = {'I',' ','l','o','v','e',' ','y','o','u'};
sb.getChars(7,10,i,7);
System.out.println( "sb: "
}
}
结果为:sb: I love her!
|
以下示例对字符串进行反转:
package com.svse.lesson4;
/**
* 反转字符串
*/
public class StringBufferDemo {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("0123456789");
System.out.println( "sb.reverse(): "
}
}
结果为:sb.reverse(): 9876543210
|
以下示例设置字符序列的长度。序列将被更改为一个新的字符序列,新序列的长度由参数指定。
package com.lesson4;
/**
* 截断字符串
*/
public class StringBufferDemo {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("0123456789");
sb.setLength(5);
System.out.println( "sb: "
}
}
结果为:sb: 01234
|
7 Random随机类
此类用来产生随机数,位于java.util包中,所以需要手工导包。
7.1 构造方法
构造器 | 描述 |
Random() | 创建一个新的随机数发生器 |
Random(long seed) | 用一个种子(长整型)创建一个随机数发生器 |
7.2 方法
说明:
1. 所有方法均为public;
2. 书写格式:[修饰符]<返回类型> <方法名([参数列表])>
请注意nextInt(int n)的取值范围及其和nextInt()方法的区别。
7.3 关于Random类的说明
Random这个类的对象使用一个48位的种子,如果这个类的两个实例是用同一个种子创建的,并且,各自对它们以同样的顺序调用方法,则它们会产生相同的数字序列。
下面就对上面的介绍做一个演示,尤其注意相同种子时的结果,如果用默认的构造函数构造对象,它们是属于同一个种子的;演示代码如下所示:
示例
package com.lesson4;
import java.util.Random;
/**
* 根据随机种子获得随机序列
*/
public class RandomDemo {
public static void main(String[] args) {
Random r1 = new Random(50);
System.out.println("第一个种子为50的Random对象");
System.out.println("r1.nextBoolean():\t"
System.out.println("r1.nextInt():\t\t"
System.out.println("r1.nextDouble():\t"
System.out.println("r1.nextGaussian():\t"
System.out.println("---------------------------");
Random r2 = new Random(50);
System.out.println("第二个种子为50的Random对象");
System.out.println("r2.nextBoolean():\t"
System.out.println("r2.nextInt():\t\t"
System.out.println("r2.nextDouble():\t"
System.out.println("r2.nextGaussian():\t"
System.out.println("---------------------------");
Random r3 = new Random(100);
System.out.println("种子为100的Random对象");
System.out.println("r3.nextBoolean():\t"
System.out.println("r3.nextInt():\t\t"
System.out.println("r3.nextDouble():\t"
System.out.println("r3.nextGaussian():\t"
System.out.println("结果一目了然!");
}
}
结果:
第一个种子为50的Random对象
r1.nextBoolean(): true
r1.nextInt(): -1727040520
r1.nextDouble(): 0.6141579720626675
r1.nextGaussian(): 2.377650302287946
---------------------------
第二个种子为50的Random对象
r2.nextBoolean(): true
r2.nextInt(): -1727040520
r2.nextDouble(): 0.6141579720626675
r2.nextGaussian(): 2.377650302287946
---------------------------
种子为100的Random对象
r3.nextBoolean(): true
r3.nextInt(): -1139614796
r3.nextDouble(): 0.19497605734770518
r3.nextGaussian(): 0.6762208162903859
|
8 Date时间类
Java在日期类中封装了有关日期和时间的信息,类 Date 表示特定的瞬间,精确到毫秒。用户可以通过调用相应的方法来获取系统时间或设置日期和时间。
8.1 构造方法
构造器名称 | 描述 |
Date() | 创建的日期类对象的日期时间被设置成创建时刻相对应的日期时间 |
Date(long date) | long型的参数date可以通过调用Date类中的static方法parse(Strings)来获得 |
8.2 方法
示例:
package com.svse.lesson4;
import java.util.Date;
/**
* Date类的基本用法
* @author svse
*
*/
public class DateDemo {
public static void main(String[] args) {
Date date1 = new Date();
Date date2 = new Date(1233997578421L);
//输出date1、date2对象所对应的毫秒数
System.out.println(date1.getTime());
System.out.println(date2.getTime());
//查看date1是否在date2后
boolean isAfter = date1.after(date2);
System.out.println("is date1 after date2:"+isAfter);
date1.setTime(1133997578421L);
isAfter = date1.after(date2);
System.out.println("is date1 after date2:"+isAfter);
}
}
|
运行结果如下:
Date类的方法
9 Calendar日历类
在历史上有着许多种纪元的方法,它们的差异实在太大了,不同的开发商也会开发出不同的日历计算方式。比如说一个人的生日是“八月八日” 那么一种可能是阳(公)历的八月八日,但也可以是阴(农)历的日期。所以为了计时的统一,必需指定一个日历的选择。那现在最为普及和通用的日历就是 “Gregorian Calendar”——格里高利历。也就是我们在讲述年份时常用 “公元几几年”。Calendar 抽象类定义了足够的方法,让我们能够表述Gregorian Calendar的规则。它为特定瞬间与一组诸如 YEAR、MONTH、DAY_OF_MONTH、HOUR 等日历字段之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法。瞬间可用毫秒值来表示,它是距历元(即格林威治标准时间 1970 年 1 月 1 日的 00:00:00.000,格里高利历)的偏移量。
注意,由于Calendar类是一个抽象类,所以不能直接通过new关键字创建Calendar类的实例,可以借助于该类提供的静态方法getInstance()来获得一个Calendar对象。正像Date类的默认构造方法一样,该对象所代表的日期正是当前系统日期:
Calendar rightNow = Calendar.getInstance();
Calendar抽象类有一个具体子类:GregorianCalendar。
9.1 字段
字段名称 | 描述 |
static int AM | 指示从午夜到中午之前这段时间的 AM_PM 字段值。 |
static int AM_PM | get 和 set 的字段数字,指示 HOUR 是在中午之前还是在中午之后。 |
static int DATE | get 和 set 的字段数字,指示一个月中的某天。 |
static int DAY_OF_MONTH | get 和 set 的字段数字,指示一个月中的某天。 |
static int DAY_OF_WEEK | get 和 set 的字段数字,指示一个星期中的某天。 |
static int DAY_OF_WEEK_IN_MONTH | get 和 set 的字段数字,指示当前月中的第几个星期。 |
static int AY_OF_YEAR | get 和 set 的字段数字,指示当前年中的天数。 |
static int HOUR | get 和 set 的字段数字,指示上午或下午的小时。 |
static int HOUR_OF_DAY | get 和 set 的字段数字,指示一天中的小时。 |
static int MILLISECOND | get 和 set 的字段数字,指示一秒中的毫秒。 |
static int MINUTE | get 和 set 的字段数字,指示一小时中的分钟。 |
static int MONTH | 指示月份的 get 和 set 的字段数字。 |
static int PM | 指示从中午到午夜之前这段时间的 AM_PM 字段值。 |
static int SECOND | get 和 set 的字段数字,指示一分钟中的秒。 |
protected long time | 日历的当前设置时间,以毫秒为单位,表示自格林威治标准时间 1970 年 1月 1 日 0:00:00 后经过的时间。 |
static int WEEK_OF_MONTH | get 和 set 的字段数字,指示当前月中的星期数。 |
static int WEEK_OF_YEAR | get 和 set 的字段数字,指示当前年中的星期数。 |
static int YEAR | 指示年的 get 和 set 的字段数字。 |
9.2 方法
请各位观察API中Calendar类常见的字段和方法,可以发现,这些方法,有的是抽象的,有的是最终方法(final),还有的是静态方法,这体现了程序设计的严谨性:在不同的环境下,不同的需求将导致不同的方法设计。
可能有同学会想不通,该类是一个抽象类,其中有一个抽象方法add(),那么add()方法能不能使用呢?我们慢慢来分析,由于Calendar类是抽象类,我们在获得Calendar实例时,使用的是getInstance()方法,其实,该方法返回的是Calendar类的子类对象,该子类为GregorianCalendar,也就是说,“Calendar ca = Calendar.getInstance()”其实是让ca引用了子类GregorianCalendar的对象,相当于Calendar ca = new GregorianCalendar(),这在语法上是允许的,并且前面的课程中也做过相应介绍。对于GregorianCalendar类来说,其内部实现了抽象的add()方法,所以,我们如果让ca调用add()方法,事实上是调用了GregorianCalendar类的add()方法,是没有任何问题的。
示例:
package com.lesson4;
import java.util.Calendar;
import java.util.Date;
/**
* Calendar类的常见方法
*/
public class CalendarDemo {
public static void main(String[] args) {
//创建Calendar实例
Calendar ca = Calendar.getInstance();
//获得ca所包含的年份。注意写法
System.out.println("year is :"+ca.get(Calendar.YEAR));
//为年份增加2
ca.add(Calendar.YEAR, 2);
System.out.println("year is :"+ca.get(Calendar.YEAR));
//设置ca的年份
ca.set(Calendar.YEAR,2009);
System.out.println("year is :"+ca.get(Calendar.YEAR));
//今天是今年的第几天
System.out.println("day of year:"+ca.get(Calendar.DAY_OF_YEAR));
//今天是本周的第几天,注意默认情况下周日是第一天
System.out.println("day of week : "+ca.get(Calendar.DAY_OF_WEEK));
//获得对应的Date对象
Date date = ca.getTime();
System.out.println("date time : "+date.getTime());
System.out.println("calendar time : "+ca.getTimeInMillis());
}
}
|
执行程序,运行结果如下:
10 SimpleDateFormat日历格式化
SimpleDateFormat类可以对Date及字符串进行分析,并在它们之间相互转换,它允许格式化 (date -> text)、语法分析 (text -> date)和标准化。它的继承关系如下:
java.lang.Object
+----java.text.Format
+----java.text.DateFormat
+----java.text.SimpleDateFormat
示例演示了该类在JavaBean内提供日期时间服务的通常用法:
package com.lesson4;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* SimpleDateFormat对日期和时间进行格式化
*/
public class FormatDateTime {
/** 长日期格式*/
public static String toLongDateString(Date dt) {
SimpleDateFormat myFmt = new SimpleDateFormat(
"yyyy年MM月dd日 HH时mm分ss秒 E ");
return myFmt.format(dt);
}
/** 短日期格式*/
public static String toShortDateString(Date dt) {
SimpleDateFormat myFmt = new SimpleDateFormat("yy年MM月dd日 HH时mm分");
return myFmt.format(dt);
}
/** 长时间格式*/
public static String toLongTimeString(Date dt) {
SimpleDateFormat myFmt = new SimpleDateFormat("HH mm ss SSSS");
return myFmt.format(dt);
}
/**短时间格式*/
public static String toShortTimeString(Date dt) {
SimpleDateFormat myFmt = new SimpleDateFormat("yy/MM/dd HH:mm");
return myFmt.format(dt);
}
/**main方法进行测试*/
public static void main(String[] args) {
Date now = new Date();
System.out.println(FormatDateTime.toLongDateString(now));
System.out.println(FormatDateTime.toShortDateString(now));
System.out.println(FormatDateTime.toLongTimeString(now));
System.out.println(FormatDateTime.toShortTimeString(now));
}
}
|
运行效果如下:
4.11 Math算术运算类
Math类中的静态方法帮助我们完成基本的数学运算,它的定义形式为:
public final class Math extends Object
可以看出,Math类是一个最终类,也就是说,它不能被继承,更不能被重写,Sun公司的牛人们不乐意看到它被别人改动,Math类中的方法全部为静态方法,直接使用就行。
示例:
package com.lesson4;
/**
* Math类的用法
*/
public class MathDemo {
public static void main(String[] args) {
// 绝对值
System.out.println("abs of -1 : " + Math.abs(-1));
// 比这个数大的最小整数
System.out.println("ceil of 9.01 : " + Math.ceil(9.01));
// 比这个数小的最大整数
System.out.println("floor of 9.99 :" + Math.floor(9.99));
// 取较大者
System.out.println("the max is : " + Math.max(101, 276.001));
// 随机数,区间为[0.0,1.0)
System.out.println("random number : " + Math.random());
// 四舍五入
System.out.println("round value of 9.49 :" + Math.round(9.49));
// 返回正确舍入的 double 值的正平方根
System.out.println("square root of 225 : " + Math.sqrt(225));
}
}
|
运行后结果如下: