一、String类
1、String介绍
String表示字符串,所谓字符串,就是一连串的字符;
String是不可变类,一旦String对象被创建,包含在对象中的字符序列(内容)是不可变的,直到对象被销毁;
常量池:JVM中一块独立的区域存放字符串常量和基本类型常量(public static final)。
String使用private final char value[]来实现字符串的存储,也就是说String对象创建之后,就不能再修改此对象中存储的字符串内容,就是因为如此,才说String类型是不可变的。
String对象比较:
单独使用""引号创建的字符串都是常量,编译期就已经确定存储到常量池中;
使用new String("")创建的对象会存储到堆内存中,是运行期新创建的;
使用只包含常量的字符串连接符如"aa" + "bb"创建的也是常量,编译期就能确定,已经确定存储到常量池中;
使用包含变量的字符串连接符如"aa" + s1创建的对象是运行期才创建的,存储在堆中;
eg:
public class StringDemo {
public static void main(String[] args) {
/*
String() 初始化一个新创建的 String对象,使其表示一个空字符序列;
""不是表示 null;
String(String original);
String s = new String("asd");// s的值就是 asd
*/
String s = "";
s = new String();
String s1 = new String("11");
String s2 = new String("11");
System.out.println(s1 == s2);//false
String s3 = "22";
String s4 = "22";
System.out.println(s3 == s4);//true
System.out.println(s3 == s2);//false
String s5 = "2" + "2";//这句话其实在编译器编译后的class文件中已经变成 "22";
//s5创建了几个对象?
//回答:最多一个,如果常量池里面没有就是创建一个,如果常量池里本来就有就是创建零个!下面的str一样的道理。
String str = "A" +"B"+ "C" +"D" +"E";//String str = "ABCDE";
System.out.println(s3 == s5);//true
/*
String特点: 不可变的, 一个String对象的内容不能变,一旦内容变量该对象就变成一个新的String对象了。
String str = "AAA";
str = str+"12";
*/
String str1 = "ABCDE";
System.out.println(str == str1);//true
String str2 = "ABC" + "DE";
System.out.println(str == str2);//true
String ss = "AB";
String str3 = ss + "CDE";//这里的str3在运行期才能确定内容值;
System.out.println(str3 == str2);//false
String str4 = getStr() +"CDE";//在运行期才能确定 str4的值;
System.out.println(str == str4);//false
System.out.println(str3 == str4);//false
/*
String s = "cd"; //一个String对象
s = s + "itcast"; //itcast也是String对象,最后的s的值cditcast,也是一个String对象;
System.out.print(s);
*/
}
public static String getStr(){
return "AB";
}
}
eg:
package demo;
public class StrDemo {
public static void main(String[] args) {
//s1,s2只新建了一个对象
String s1 = "你好";
String s2 = "你好";
//s3,s4新建了两个对象
String s3 = new String("你好");
String s4 =new String( "你好");
}
}
2、String类的常用方法
String():初始化一个新的 String对象,使其表示一个空字符序列,并不是返回空(不等于null);
String(StringBuffer buffer):根据StringBuffer对象来创建String对象;
String(StringBuilder builder):同上
char charAt(int index):取字符串中指定位置的字符,index从0开始计算;
String concat(String str):连接字符串,等同于“+”;
boolean contentEquals(StringBuffer buffer):若二者包含的字符序列相同时就返回true;
boolean equals(Object obj):将该字符串与指定对象比较,若二者包含的字符序列相等返回true;
boolean equalsIgnoreCase(String anotherString):将此 String与另一个 String比较,不考虑大小写;
byte[] getBytes():将该字符串转换成byte数组;
int indexOf(String str):找出str字符串在该字符串中第一次出现的位置;
int indexOf(String str, int fromIndex):返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始;
int lastIndexOf(String str):返回指定子字符串在此字符串中最后一次出现处的索引;
int length():返回当前字符串长度;
String replace(char oldChar, char newChar) :返回一个新的字符串,它是通过用 newChar替换此字符串中出现的所有 oldChar得到的;
String replaceAll(String regex, String replacement):使用给定的字符串replacement替换此字符串所有的regex字符串;
boolean startsWith(String prefix):测试此字符串是否以指定的前缀开始;
String[] split(String regex):把字符串按指定的字符串分隔开;
String substring(int beginIndex):返回一个新的字符串,从beginIndex开始截取,它是此字符串的一个子字符串;
String substring(int beginIndex, int endIndex):返回一个新字符串,它是此字符串的一个子字符串;
char[] toCharArray():将此字符串转换为一个新的字符数组;
String toLowerCase():将此 String中的所有字符都转换为小写;
String toUpperCase():转成大写;
static String valueOf(基本类型 obj):把基本类型值转成字符串;
String trim() :忽略字符串前导空白和尾部空白;
String小例子:
判断字符串是否由数字组成:
package demo;
public class StrDemo2 {
public static void main(String[] args) {
String s1 = "123456789";
String s2 = "12345 6789";
System.out.print(isNum(s1));
System.out.print(isNum(s2));
}
public static boolean isNum(String s){
char []ch = s.toCharArray();
for (char c : ch) {
if(!(c >= '0' && c <= '9')){
return false;
}
}
return true;
}
}
输出:true false
<span style="color:black;"></span>
二、StringBuilder与StringBuffer类
String是不可变类,一旦String对象被创建,包含在对象中的字符序列是不可变的,直到对象被销毁;StringBuffer 与StringBuilder对象则是可变的!举例说明这两个的好处:(不用每次新建对象,效率高!)
package demo;
public class StrDemo2 {
public static void main(String[] args) {
String s = "";
long begintime = System.currentTimeMillis();
for(int i = 1;i <= 100000;i++){
s += i;
}
long endtime = System.currentTimeMillis();
long time = endtime - begintime;
System.out.println("运行时间为:"+time);
StringBuffer s1 = new StringBuffer();
begintime = System.currentTimeMillis();
for(int i = 1;i <= 100000;i++){
s1 = s1.append(i);
}
endtime = System.currentTimeMillis();
time = endtime - begintime;
System.out.println("运行时间为:"+time);
}
}
输出:
运行时间为:82922
运行时间为:15
StringBuffer: 是线程安全的;
StringBuilder:是线程不安全的,性能高点,推荐使StringBuilder;(jdk1.5出现);
StringBuffer 和 String之间的转换:
String toString() 返回此序列中数据的字符串表示形式。
StringBuffer(String str):以指定的字符串创建StringBuffer对象。
StringBuffer与StringBuilder的用法类似且它们所具有的方法也很相似。StringBuilder的常用方法如下:
构造方法摘要 | |
StringBuilder() 构造一个不带任何字符的字符串生成器,其初始容量为 16个字符。 | |
StringBuilder(int capacity) 构造一个不带任何字符的字符串生成器,其初始容量由 capacity参数指定。 | |
StringBuilder(String str) 构造一个字符串生成器,并初始化为指定的字符串内容。 | |
方法摘要 | |
StringBuilder | append(type lng) 将 type类型参数的字符串表示形式追加到此序列。 |
StringBuilder | append(Object obj) 追加 Object参数的字符串表示形式。 |
StringBuilder | append(String str) 将指定的字符串追加到此字符序列。 |
StringBuilder | append(StringBuffer sb) 将指定的 StringBuffer追加到此序列。 |
int | capacity() 返回当前容量。 |
char | charAt(int index) 返回此序列中指定索引处的 char值。 |
StringBuilder | delete(int start, int end) 移除此序列的子字符串中的字符。 |
StringBuilder | deleteCharAt(int index) 移除此序列指定位置上的 char。 |
void | ensureCapacity(int minimumCapacity) 确保容量至少等于指定的最小值。 |
void | getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) 将字符从此序列复制到目标字符数组 dst。 |
int | indexOf(String str) 返回第一次出现的指定子字符串在该字符串中的索引。 |
int | indexOf(String str, int fromIndex) 从指定的索引处开始,返回第一次出现的指定子字符串在该字符串中的索引。 |
StringBuilder | insert(int offset, type b) 将 type参数的字符串表示形式插入此序列中。 |
StringBuilder | insert(int offset, Object obj) 将 Object参数的字符串表示形式插入此字符序列中。 |
StringBuilder | insert(int offset, String str) 将字符串插入此字符序列中。 |
int | lastIndexOf(String str) 返回最右边出现的指定子字符串在此字符串中的索引。 |
int | lastIndexOf(String str, int fromIndex) 返回最后一次出现的指定子字符串在此字符串中的索引。 |
int | length() 返回长度(字符数)。 |
StringBuilder | replace(int start, int end, String str) 使用给定 String中的字符替换此序列的子字符串中的字符。 |
StringBuilder | reverse() 将此字符序列用其反转形式取代。 |
void | setCharAt(int index, char ch) 将给定索引处的字符设置为 ch。 |
void | setLength(int newLength) 设置字符序列的长度。 |
String | substring(int start) 返回一个新的 String,它包含此字符序列当前所包含字符的子序列。 |
String | substring(int start, int end) 返回一个新的 String,它包含此序列当前所包含字符的子序列。 |
String | toString() 返回此序列中数据的字符串表示形式。 |
如下是几个简单的例子:
eg:
package demo;
/*
用StringBuilder或StringBuffer:
把字符串“ABCDE”;
转变成字符串“A,B,C,D”
*/
public class StrBuilderDemo {
public static void main(String[] args) {
//第一种方法:往里面插入;
StringBuilder sb = new StringBuilder("ABCDE");
sb.deleteCharAt(sb.length()-1);
System.out.println(sb);
for (int i = 0; i < sb.length(); i+=2) {
sb.insert(i, ",");
}
sb.deleteCharAt(0);
System.out.println(sb);
//第二种方法:往里面追加,要追加必须遍历,必须换为数组!
sb = new StringBuilder("ABCDE");
sb.deleteCharAt(sb.length()-1);
System.out.println(sb);
char []cs = sb.toString().toCharArray();
StringBuilder sb1 = new StringBuilder();
for (char c : cs) {
sb1.append(c).append(",");
}
sb1.deleteCharAt(sb1.length()-1);
System.out.println(sb1);
}
}
package demo;
/*
编写一个程序,
这个程序把一个整数数组中的每个元素用逗号连接成一个字符串,
例如,根据内容为{1,2,3}的数组形成内容为"1,2,3"的字符串。
*/
public class StrDemo4 {
public static void main(String[] args) {
int []i = {1,2,3,4,5};
StringBuilder sb = new StringBuilder();
for (int j : i) {
sb.append(j).append(",");
}
sb.deleteCharAt(sb.length()-1);
System.out.println(sb);
}
}
三、Math和Random和UUID类
1、Math类
Math 类包含用于执行基本数学运算的方法,为三角函数、对数函数和其他通用数学函数提供常数和静态方法。
字段摘要 | |
static double | E 比任何其他值都更接近 e(即自然对数的底数)的 double值。 |
static double | PI 比任何其他值都更接近 pi(即圆的周长与直径之比)的 double值。 |
static type | abs(type a) 返回 type类型值的绝对值。 |
static double | acos(double a) 返回一个值的反余弦;返回的角度范围在 0.0到 pi之间。 |
static double | asin(double a) 返回一个值的反正弦;返回的角度范围在 -pi/2到 pi/2之间。 |
static double | atan(double a) 返回一个值的反正切;返回的角度范围在 -pi/2到 pi/2之间。 |
static double | atan2(double y, double x) 将矩形坐标 (x, y)转换成极坐标 (r, theta),返回所得角 theta。 |
static double | cbrt(double a) 返回 double值的立方根。 |
static double | ceil(double a) 返回最小的(最接近负无穷大)double值,该值大于等于参数,并等于某个整数。 |
static double | cos(double a) 返回角的三角余弦。 |
static double | exp(double a) 返回欧拉数 e的 double次幂的值。 |
static double | floor(double a) 返回最大的(最接近正无穷大)double值,该值小于等于参数,并等于某个整数。 |
static double | log(double a) 返回 double值的自然对数(底数是 e)。 |
static double | log10(double a) 返回 double值的底数为 10的对数。 |
static type | max(type a, type b) 返回两个 type类型值中较大的一个。 |
static type | min(type a, type b) 返回两个 type类型值中较小的一个。 |
static double | pow(double a, double b) 返回第一个参数的第二个参数次幂的值。 |
static double | random() 返回带正号的 double值,该值大于等于 0.0且小于 1.0。 |
static double | rint(double a) 返回最接近参数并等于某一整数的 double值。 |
static long | round(double a) 返回最接近参数的 long。 |
static int | round(float a) 返回最接近参数的 int。 |
static double | sin(double a) 返回角的三角正弦。 |
static double | sinh(double x) 返回 double值的双曲线正弦。 |
static double | sqrt(double a) 返回正确舍入的 double值的正平方根。 |
static double | tan(double a) 返回角的三角正切。 |
static double | tanh(double x) 返回 double值的双曲线余弦。 |
eg:
public class MathDemo {
public static void main(String args[]){
// abs求绝对值
System.out.println(Math.abs(-10.4)); //10.4
System.out.println(Math.abs(10.1)); //10.1
// ceil天花板的意思,返回最小的(最接近负无穷大)double值,该值大于等于参数,并等于某个整数。
System.out.println(Math.ceil(-10.1)); //-10.0
System.out.println(Math.ceil(10.7)); //11.0
System.out.println(Math.ceil(-0.7)); //-0.0
System.out.println(Math.ceil(0.0)); //0.0
System.out.println(Math.ceil(-0.0)); //-0.0
// floor地板的意思,返回最大的(最接近正无穷大)double值,该值小于等于参数,并等于某个整数。
System.out.println(Math.floor(-10.1)); //-11.0
System.out.println(Math.floor(10.7)); //10.0
System.out.println(Math.floor(-0.7)); //-1.0
System.out.println(Math.floor(0.0)); //0.0
System.out.println(Math.floor(-0.0)); //-0.0
// max 两个中返回大的值,min和它相反,就不举例了
System.out.println(Math.max(-10.1, -10)); //-10.0
System.out.println(Math.max(10.7, 10)); //10.7
System.out.println(Math.max(0.0, -0.0)); //0.0
// random 取得一个大于或者等于0.0小于不等于1.0的随机数
System.out.println(Math.random()); //0.08417657924317234
System.out.println(Math.random()); //0.43527904004403717
// rint 四舍五入,返回double值
// 注意.5的时候会取偶数
System.out.println(Math.rint(10.1)); //10.0
System.out.println(Math.rint(10.7)); //11.0
System.out.println(Math.rint(11.5)); //12.0
System.out.println(Math.rint(10.5)); //10.0
System.out.println(Math.rint(10.51)); //11.0
System.out.println(Math.rint(-10.5)); //-10.0
System.out.println(Math.rint(-11.5)); //-12.0
System.out.println(Math.rint(-10.51)); //-11.0
System.out.println(Math.rint(-10.6)); //-11.0
System.out.println(Math.rint(-10.2)); //-10.0
// round 四舍五入,float时返回int值,double时返回long值
System.out.println(Math.round(10.1)); //10
System.out.println(Math.round(10.7)); //11
System.out.println(Math.round(10.5)); //11
System.out.println(Math.round(10.51)); //11
System.out.println(Math.round(-10.5)); //-10
System.out.println(Math.round(-10.51));//-11
System.out.println(Math.round(-10.6)); //-11
System.out.println(Math.round(-10.2)); //-10
}
}
2、Random类 (java.util)
Random类中实现的随机算法是伪随机,也就是有规则的随机。在进行随机时,随机算法的起源数字称为种子数(seed),在种子数的基础上进行一定的变换,从而产生需要的随机数字。
相同种子数的Random对象,相同次数生成的随机数字是完全相同的。也就是说,两个种子数相同的Random对象,第一次生成的随机数字完全相同,第二次生成的随机数字也完全相同。这点在生成多个随机数字时需要特别注意。
下面介绍一下Random类的使用,以及如何生成指定区间的随机数组以及实现程序中要求的几率。
1)、Random对象的生成
Random类包含两个构造方法,下面依次进行介绍:
a、public Random()
该构造方法使用一个和当前系统时间对应的相对时间有关的数字作为种子数,然后使用这个种子数构造Random对象。
b、public Random(long seed)
该构造方法可以通过制定一个种子数进行创建。
示例代码:
Random r = new Random();
Random r1 = new Random(10);
再次强调:种子数只是随机算法的起源数字,和生成的随机数字的区间无关。
2)、Random类中的常用方法
Random类中的方法比较简单,每个方法的功能也很容易理解。需要说明的是,Random类中各方法生成的随机数字都是均匀分布的,也就是说区间内部的数字生成的几率是均等的。下面对这些方法做一下基本的介绍:
a、public boolean nextBoolean()
该方法的作用是生成一个随机的boolean值,生成true和false的值几率相等,也就是都是50%的几率。
b、public double nextDouble()
该方法的作用是生成一个随机的double值,数值介于[0,1.0)之间。
c、public int nextInt()
该方法的作用是生成一个随机的int值,该值介于int的区间,也就是-231到231-1之间。
如果需要生成指定区间的int值,则需要进行一定的数学变换,具体可以参看下面的使用示例中的代码。
d、public int nextInt(int n)
该方法的作用是生成一个随机的int值,该值介于[0,n)的区间,也就是0到n之间的随机int值,包含0而不包含n。
如果想生成指定区间的int值,也需要进行一定的数学变换,具体可以参看下面的使用示例中的代码。
e、public void setSeed(long seed)
该方法的作用是重新设置Random对象中的种子数。设置完种子数以后的Random对象和相同种子数使用new关键字创建出的Random对象相同。
3)、Random类使用示例
使用Random类,一般是生成指定区间的随机数字,下面就一一介绍如何生成对应区间的随机数字。以下生成随机数的代码均使用以下Random对象r进行生成:
Random r = new Random();
a、生成[0,1.0)区间的小数
double d1 = r.nextDouble();
直接使用nextDouble方法获得。
b、生成[0,5.0)区间的小数
double d2 = r.nextDouble() * 5;
因为nextDouble方法生成的数字区间是[0,1.0),将该区间扩大5倍即是要求的区间。
同理,生成[0,d)区间的随机小数,d为任意正的小数,则只需要将nextDouble方法的返回值乘以d即可。
c、生成[1,2.5)区间的小数
double d3 = r.nextDouble() * 1.5 + 1;
生成[1,2.5)区间的随机小数,则只需要首先生成[0,1.5)区间的随机数字,然后将生成的随机数区间加1即可。
同理,生成任意非从0开始的小数区间[d1,d2)范围的随机数字(其中d1不等于0),则只需要首先生成[0,d2-d1)区间的随机数字,然后将生成的随机数字区间加上d1即可。
d、生成任意整数
int n1 = r.nextInt();
直接使用nextInt方法即可。
e、生成[0,10)区间的整数
int n2 = r.nextInt(10);
n2 = Math.abs(r.nextInt() % 10);
以上两行代码均可生成[0,10)区间的整数。
第一种实现使用Random类中的nextInt(int n)方法直接实现。
第二种实现中,首先调用nextInt()方法生成一个任意的int数字,该数字和10取余以后生成的数字区间为(-10,10),然后再对该区间求绝对值,则得到的区间就是[0,10)了。
同理,生成任意[0,n)区间的随机整数,都可以使用如下代码:
int n2 = r.nextInt(n);
n2 = Math.abs(r.nextInt() % n);
f、生成[0,10]区间的整数
int n3 = r.nextInt(11);
n3 = Math.abs(r.nextInt() % 11);
相对于整数区间,[0,10]区间和[0,11)区间等价,所以即生成[0,11)区间的整数。
g、生成[-3,15)区间的整数
int n4 = r.nextInt(18) - 3;
n4 = Math.abs(r.nextInt() % 18) - 3;
生成非从0开始区间的随机整数,可以参看上面非从0开始的小数区间实现原理的说明。
h、几率实现
按照一定的几率实现程序逻辑也是随机处理可以解决的一个问题。下面以一个简单的示例演示如何使用随机数字实现几率的逻辑。
在前面的方法介绍中,nextInt(int n)方法中生成的数字是均匀的,也就是说该区间内部的每个数字生成的几率是相同的。那么如果生成一个[0,100)区间的随机整数,则每个数字生成的几率应该是相同的,而且由于该区间中总计有100个整数,所以每个数字的几率都是1%。按照这个理论,可以实现程序中的几率问题。
示例:随机生成一个整数,该整数以55%的几率生成1,以40%的几率生成2,以5%的几率生成3。实现的代码如下:
int n5 = r.nextInt(100);
int m; //结果数字
if(n5 < 55){ //55个数字的区间,55%的几率
m = 1;
}else if(n5 < 95){ //[55,95),40个数字的区间,40%的几率
m = 2;
}else{
m = 3;
}
因为每个数字的几率都是1%,则任意55个数字的区间的几率就是55%,为了代码方便书写,这里使用[0,55)区间的所有整数,后续的原理一样。
当然,这里的代码可以简化,因为几率都是5%的倍数,所以只要以5%为基础来控制几率即可,下面是简化的代码实现:
int n6 = r.nextInt(20);
int m1;
if(n6 < 11){
m1 = 1;
}else if(n6 < 19){
m1= 2;
}else{
m1 = 3;
}
在程序内部,几率的逻辑就可以按照上面的说明进行实现。
4)、其它问题
a、相同种子数Random对象问题
前面介绍过,相同种子数的Random对象,相同次数生成的随机数字是完全相同的,下面是测试的代码:
Random r1 = new Random(10);
Random r2 = new Random(10);
for(int i = 0;i < 2;i++){
System.out.println(r1.nextInt());
System.out.println(r2.nextInt());
}
在该代码中,对象r1和r2使用的种子数都是10,则这两个对象相同次数生成的随机数是完全相同的。
如果想避免出现随机数字相同的情况,则需要注意,无论项目中需要生成多少个随机数字,都只使用一个Random对象即可。
b、关于Math类中的random方法
其实在Math类中也有一个random方法,该random方法的工作是生成一个[0,1.0)区间的随机小数。
通过阅读Math类的源代码可以发现,Math类中的random方法就是直接调用Random类中的nextDouble方法实现的。
只是random方法的调用比较简单,所以很多程序员都习惯使用Math类的random方法来生成随机数字。
3、UUID类
唯一标识符 (UUID)的类, UUID表示一个 128位的值。
UUID(Universally Unique Identifier)全局唯一标识符,是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的。按照开放软件基金会(OSF)制定的标准计算,用到了以太网卡地址、纳秒级时间、芯片ID码和许多可能的数字。由以下几部分的组合:当前日期和时间(UUID的第一个部分与时间有关,如果你在生成一个UUID之后,过几秒又生成一个UUID,则第一个部分不同,其余相同),时钟序列,全局唯一的IEEE机器识别号(如果有网卡,从网卡获得,没有网卡以其他方式获得),UUID的唯一缺陷在于生成的结果串会比较长。
标准的UUID格式为:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx (8-4-4-4-12),其中每个 x是 0-9或 a-f范围内的一个十六进制的数字;
UUID uuid = UUID.randomUUID();
String uid = uuid.toString();
四、Date和Calendar类
1、Date类
在JDK1.0中,Date类是唯一的一个代表时间的类,但是由于Date类不便于实现国际化,所以从JDK1.1版本开始,推荐使用Calendar类进行时间和日期处理。这里简单介绍一下Date类的使用。
1)、使用Date类代表当前系统时间
Date d = new Date();
System.out.println(d);
使用Date类的默认构造方法创建出的对象就代表当前时间,由于Date类覆盖了toString方法,所以可以直接输出Date类型的对象,显示的结果如下:
Sun Mar 08 16:35:58 CST 2009
在该格式中,Sun代表Sunday(周日),Mar代表March(三月),08代表8号,CST代表China Standard Time(中国标准时间,也就是北京时间(东八区))。
2)、使用Date类代表指定的时间
Date d1 = new Date(2009-1900,3-1,9);
System.out.println(d1);
使用带参数的构造方法,可以构造指定日期的Date类对象,Date类中年份的参数应该是实际需要代表的年份减去1900,实际需要代表的月份减去1以后的值。例如上面的示例代码代表就是2009年3月9号。
实际代表具体的年月日时分秒的日期对象,和这个类似。
3)、获得Date对象中的信息
Date d2 = new Date();
int year = d2.getYear() + 1900;//年份
int month = d2.getMonth() + 1;//月份
int date = d2.getDate();//日期
int hour = d2.getHours(); //小时
int minute = d2.getMinutes();//分钟
int second = d2.getSeconds();//秒
int day = d2.getDay();//星期几
System.out.println("年份:" + year);
System.out.println("月份:" + month);
System.out.println("日期:" + date);
System.out.println("小时:" + hour);
System.out.println("分钟:" + minute);
System.out.println("秒:" + second);
System.out.println("星期:" + day);
使用Date类中对应的get方法,可以获得Date类对象中相关的信息,需要注意的是使用getYear获得是Date对象中年份减去1900以后的值,所以需要显示对应的年份则需要在返回值的基础上加上1900,月份类似。在Date类中还提供了getDay方法,用于获得Date对象代表的时间是星期几,Date类规定周日是0,周一是1,周二是2,后续的依次类推。
4)、Date对象和相对时间之间的互转
Date date3 = new Date(2009-1900,3-1,10);
long time = 1290876532190L;
//将Date类的对象转换为相对时间
long t = date3.getTime();
System.out.println(t);
//将相对时间转换为Date类的对象
Date date4 = new Date(time);
System.out.println(date4);
使用Date对象中的getTime方法,可以将Date类的对象转换为相对时间,使用Date类的构造方法,可以将相对时间转换为Date类的对象。经过转换以后,既方便了时间的计算,也使时间显示比较直观了。
2、 Calendar类
从JDK1.1版本开始,在处理日期和时间时,系统推荐使用Calendar类进行实现。在设计上,Calendar类的功能要比Date类强大很多,而且在实现方式上也比Date类要复杂一些,下面就介绍一下Calendar类的使用。
Calendar类是一个抽象类,在实际使用时实现特定的子类的对象,创建对象的过程对程序员来说是透明的,只需要使用getInstance方法创建即可。
1)、使用Calendar类代表当前时间
Calendar c = Calendar.getInstance();
由于Calendar类是抽象类,且Calendar类的构造方法是protected的,所以无法使用Calendar类的构造方法来创建对象,API中提供了getInstance方法用来创建对象。
使用该方法获得的Calendar对象就代表当前的系统时间,由于Calendar类toString实现的没有Date类那么直观,所以直接输出Calendar类的对象意义不大。
2)、使用Calendar类代表指定的时间
Calendar c1 = Calendar.getInstance();
c1.set(2009, 3 - 1, 9);
使用Calendar类代表特定的时间,需要首先创建一个Calendar的对象,然后再设定该对象中的年月日参数来完成。
set方法的声明为:
public final void set(int year,int month,int date)
以上示例代码设置的时间为2009年3月9日,其参数的结构和Date类不一样。Calendar类中年份的数值直接书写,月份的值为实际的月份值减1,日期的值就是实际的日期值。
如果只设定某个字段,例如日期的值,则可以使用如下set方法:
public void set(int field,int value)
在该方法中,参数field代表要设置的字段的类型,常见类型如下:
Calendar.YEAR——年份
Calendar.MONTH——月份
Calendar.DATE——日期
Calendar.DAY_OF_MONTH——日期,和上面的字段完全相同
Calendar.HOUR——12小时制的小时数
Calendar.HOUR_OF_DAY——24小时制的小时数
Calendar.MINUTE——分钟
Calendar.SECOND——秒
Calendar.DAY_OF_WEEK——星期几
后续的参数value代表,设置成的值。例如:
c1.set(Calendar.DATE,10);
该代码的作用是将c1对象代表的时间中日期设置为10号,其它所有的数值会被重新计算,例如星期几以及对应的相对时间数值等。
3)、获得Calendar类中的信息
Calendar c2 = Calendar.getInstance();
int year = c2.get(Calendar.YEAR);//年份
int month = c2.get(Calendar.MONTH) + 1;//月份
int date = c2.get(Calendar.DATE);//日期
int hour = c2.get(Calendar.HOUR_OF_DAY);//小时
int minute = c2.get(Calendar.MINUTE);//分钟
int second = c2.get(Calendar.SECOND);//秒
int day = c2.get(Calendar.DAY_OF_WEEK);//星期几
System.out.println("年份:" + year);
System.out.println("月份:" + month);
System.out.println("日期:" + date);
System.out.println("小时:" + hour);
System.out.println("分钟:" + minute);
System.out.println("秒:" + second);
System.out.println("星期:" + day);
使用Calendar类中的get方法可以获得Calendar对象中对应的信息,get方法的声明如下:
public int get(int field)
其中参数field代表需要获得的字段的值,字段说明和上面的set方法保持一致。需要说明的是,获得的月份为实际的月份值减1,获得的星期的值和Date类不一样。在Calendar类中,周日是1,周一是2,周二是3,依次类推。
4)、其它方法说明
其实Calendar类中还提供了很多其它有用的方法,下面简单的介绍几个常见方法的使用。
a、add方法
public abstract void add(int field,int amount)
该方法的作用是在Calendar对象中的某个字段上增加或减少一定的数值,增加是amount的值为正,减少时amount的值为负。
例如在计算一下当前时间100天以后的日期,代码如下:
Calendar c3 = Calendar.getInstance();
c3.add(Calendar.DATE, 100);
int year1 = c3.get(Calendar.YEAR);
int month1 = c3.get(Calendar.MONTH) + 1;//月份
int date1 = c3.get(Calendar.DATE); //日期
System.out.println(year1 + "年" + month1 + "月" + date1 + "日");
这里add方法是指在c3对象的Calendar.DATE,也就是日期字段上增加100,类内部会重新计算该日期对象中其它各字段的值,从而获得100天以后的日期,例如程序的输出结果可能为:
2009年6月17日
b、after方法
public boolean after(Object when)
该方法的作用是判断当前日期对象是否在when对象的后面,如果在when对象的后面则返回true,否则返回false。例如:
Calendar c4 = Calendar.getInstance();
c4.set(2009, 10 - 1, 10);
Calendar c5 = Calendar.getInstance();
c5.set(2010, 10 - 1, 10);
boolean b = c5.after(c4);
System.out.println(b);
在该示例代码中对象c4代表的时间是2009年10月10号,对象c5代表的时间是2010年10月10号,则对象c5代表的日期在c4代表的日期之后,所以after方法的返回值是true。
另外一个类似的方法是before,该方法是判断当前日期对象是否位于另外一个日期对象之前。
c、getTime方法
public final Date getTime()
该方法的作用是将Calendar类型的对象转换为对应的Date类对象,两者代表相同的时间点。
类似的方法是setTime,该方法的作用是将Date对象转换为对应的Calendar对象,该方法的声明如下:
public final void setTime(Date date)
转换的示例代码如下:
Date d = new Date();
Calendar c6 = Calendar.getInstance();
//Calendar类型的对象转换为Date对象
Date d1 = c6.getTime();
//Date类型的对象转换为Calendar对象
Calendar c7 = Calendar.getInstance();
c7.setTime(d);
5)、Calendar对象和相对时间之间的互转
Calendar c8 = Calendar.getInstance();
long t = 1252785271098L;
//将Calendar对象转换为相对时间
long t1 = c8.getTimeInMillis();
//将相对时间转换为Calendar对象
Calendar c9 = Calendar.getInstance();
c9.setTimeInMillis(t1);
在转换时,使用Calendar类中的getTimeInMillis方法可以将Calendar对象转换为相对时间。在将相对时间转换为Calendar对象时,首先创建一个Calendar对象,然后再使用Calendar类的setTimeInMillis方法设置时间即可。
应用示例
下面以两个简单的示例介绍时间和日期处理的基本使用。
/* 1、计算两个日期之间相差的天数
例如计算2010年4月1号和2009年3月11号之间相差的天数,则可以使用时间和日期处理进行计算。
该程序实现的原理为:首先代表两个特定的时间点,这里使用Calendar的对象进行代表,然后将两个时间点转换为对应的相对时间,求两个时间点相对时间的差值,然后除以1天的毫秒数(24小时X60分钟X60秒X1000毫秒)即可获得对应的天数。实现该示例的完整代码如下:
*/
import java.util.*;
public class DateDemo1 {
public static void main(String[] args) {
//设置两个日期
//日期:2009年3月11号
Calendar c1 = Calendar.getInstance();
c1.set(2009, 3 - 1, 11);
//日期:2010年4月1号
Calendar c2 = Calendar.getInstance();
c2.set(2010, 4 - 1, 1);
//转换为相对时间
long t1 = c1.getTimeInMillis();
long t2 = c2.getTimeInMillis();
//计算天数
long days = (t2 - t1)/(24 * 60 * 60 * 1000);
System.out.println(days);
}
}
/* 2、输出当前月的月历
该示例的功能是输出当前系统时间所在月的日历,例如当前系统时间是2009年3月10日,则输出2009年3月的日历。
该程序实现的原理为:首先获得该月1号是星期几,然后获得该月的天数,最后使用流程控制实现按照日历的格式进行输出即可。即如果1号是星期一,则打印一个单位的空格,如果1号是星期二,则打印两个单位的空格,依次类推。打印完星期六的日期以后,进行换行。实现该示例的完整代码如下:
*/
import java.util.*;
public class DateDemo2{
public static void main(String[] args){
//获得当前时间
Calendar c = Calendar.getInstance();
//设置代表的日期为1号
c.set(Calendar.DATE,1);
//获得1号是星期几
int start = c.get(Calendar.DAY_OF_WEEK);
//获得当前月的最大日期数
int maxDay = c.getActualMaximum(Calendar.DATE);
//输出标题
System.out.println("星期日星期一星期二星期三星期四星期五 星期六");
//输出开始的空格
for(int i = 1;i < start;i++){
System.out.print(" ");
}
//输出该月中的所有日期
for(int i = 1;i <= maxDay;i++){
//输出日期数字
System.out.print(" " + i);
//输出分隔空格
System.out.print(" ");
if(i < 10){
System.out.print(' ');
}
//判断是否换行
if((start + i - 1) % 7 == 0){
System.out.println();
}
}
//换行
System.out.println();
}
}
五、System类
System类包含一些与系统相关的类字段和方法。它不能被实例化,类中所有属性和方法都是static,可直接被System调用。
常用方法:
static void exit(int status):终止虚拟机的运行.对于发生了异常情况而想终止虚拟机的运行,传递一个非0数值,对于正常情况下退出系统传递0值;
该方法实际调用的是Runtime.getRuntime().exit(int status);
static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length):数组拷贝;
static long currentTimeMillis():返回以毫秒为单位的当前时间;
String getenv(String name):获得指定的环境变量;
static void gc() :运行垃圾回收器;
实际上调用了 Runtime中的gc()方法;
Runtime.getRuntime().exec("notepad ");
static Properties getProperties() :取得当前的系统属性;
static String getProperty(String key):取得指定键指示的系统属性;
static String getProperty(String key, String def):获取用指定键描述的系统属性,def表示默认信息;
具体用法参考如下:
字段摘要 | ||
static PrintStream | err “标准”错误输出流。 | |
static InputStream | in “标准”输入流。 | |
static PrintStream | out “标准”输出流。 | |
方法摘要 | ||
static void | arraycopy(Object src, int srcPos,Object dest, int destPos, int length) 从指定源数组中复制一个数组,复制从指定的位置开始,到目标数组的指定位置结束。 | |
static String | clearProperty(String key) 移除指定键指示的系统属性。 | |
static long | currentTimeMillis() 返回以毫秒为单位的当前时间。 | |
static void | exit(int status) 终止当前正在运行的 Java虚拟机。 | |
static void | gc() 运行垃圾回收器。 | |
static Map<String,String> | getenv() 返回一个不能修改的当前系统环境的字符串映射视图。 | |
static String | getenv(String name) 获取指定的环境变量值。 | |
static Properties | getProperties() 确定当前的系统属性。 | |
static String | getProperty(String key) 获取指定键指示的系统属性。 | |
static String | getProperty(String key,String def) 获取用指定键描述的系统属性。 | |
static void | load(String filename) 从作为动态库的本地文件系统中以指定的文件名加载代码文件。 | |
static void | loadLibrary(String libname) 加载由libname参数指定的系统库。 | |
static void | setErr(PrintStream err) 重新分配“标准”错误输出流。 | |
static void | setIn(InputStream in) 重新分配“标准”输入流。 | |
static void | setOut(PrintStream out) 重新分配“标准”输出流。 | |
static void | setProperties(Properties props) 将系统属性设置为Properties参数。 | |
static String | setProperty(String key,String value) 设置指定键指示的系统属性。 |