Step By Step(Java 常用对象篇<一>)

    本篇主要介绍的是我们在日常开发中经常用到的JDK对象,这里进行了一些分类性总结和差异比较。由于这里涉及的很多工具类都是大家耳熟能详的,因此不会长篇大论的介绍每一个概念和细节,我们还是继续秉承该系列的风格,通过更多实用的可执行的示例代码和关键性注释来阐述他们的功能和技术细节,让我们现在就开始吧。
    1.    大数值对象(BigDecimal):
    和普通的原始类型相比,该类主要提供以下几点优势:
    1)    可以表示任意大十进制数值;
    2)    提供了基本的数学函数,同时也支持各种数学运算符;
    3)    提供了与字符串(String)和原始数值类型之间的各种转换;
    4)    与double和Double相比,在进行浮点运算时不丢失精度;
    5)    提供可靠的四舍五入表示。
    那么的劣势又是什么呢?性能!因此如果我们的系统需要进行大量的科学计算,那么BigDecimal将不是一个很好的选择,特别是对那些高密度计算的程序,在这种情况下我们的首选还是原始数据类型。因此BigDecimal更适用于基于商业规则的运算程序,如保单和利息等。
    下面将给出几个比较典型的应用示例:
    1)    BigDecimal与String和任意数值类型的转换:

 1     public static void main(String args[]) {
2 BigDecimal bd1 = new BigDecimal("123456789.0123456890");
3 BigDecimal bd2 = BigDecimal.valueOf(123L);
4 bd1 = bd1.add(bd2);
5 System.out.println(bd2.toPlainString());
6 BigDecimal bd3 = new BigDecimal(bd2.toPlainString());
7 if (bd3.equals(bd2))
8 System.out.println("bd2 is equal to bd3");
9 if (bd2.intValue() == 123)
10 System.out.println("bd2 is equal to 123.");
11 }
12 /* 输出结果如下:
13 123
14 bd2 is equal to bd3
15 bd2 is equal to 123.
16 */

    由上例的输出结果可见,BigDecimal中提供了各种类型之间的可传递性转换,既上例中的bd2对象,源于123L,然后再将该对象转换会原始类型时,得到的值和之前初始化该对象的值仍然是相等的。上例中还用将bd2转换为字符串,并用该结果构造了另外一个BigDecimal对象,在比较这个两个对象的值时,发现他们是相等的。这种可传递性的类型之间的转换,Effective Java的作者是比较推崇的。
    2)    基本的数学运算和数学函数应用:

 1     public static void main(String args[]) {
2 BigDecimal bd1 = new BigDecimal("123456789.0123456890");
3 BigDecimal bd2 = BigDecimal.valueOf(123L);
4 bd1 = bd1.add(bd2);
5 System.out.printf("bd1 = %s after add.\n",bd1.toPlainString());
6 bd1 = bd1.multiply(bd2);
7 System.out.printf("bd1 = %s after multiply.\n",bd1.toPlainString());
8 bd1 = bd1.subtract(bd2);
9 System.out.printf("bd1 = %s after subtract.\n",bd1.toPlainString());
10 bd1 = bd1.divide(bd2, BigDecimal.ROUND_UP);
11 System.out.printf("bd1 = %s after divide.\n",bd1.toPlainString());
12 bd1 = bd1.negate();
13 System.out.printf("bd1 = %s after negate.\n",bd1.toPlainString());
14 System.out.println("The power of db2(123) is " + bd2.pow(2).toPlainString());
15 }
16 /* 输出结果如下:
17 bd1 = 123456912.0123456890 after add.
18 bd1 = 15185200177.5185197470 after multiply.
19 bd1 = 15185200054.5185197470 after subtract.
20 bd1 = 123456911.0123456890 after divide.
21 bd1 = -123456911.0123456890 after negate.
22 The power of db2(123) is 15129
23 */

    从结果中可以看出没有丢失精度。
    3)    基于刻度的进位:

 1     public static void main(String args[]) {
2 int decimalPlaces = 2;
3 BigDecimal bd = new BigDecimal("123456789.0123456890");
4 //始终向下舍位
5 BigDecimal bd1 = bd.setScale(decimalPlaces, BigDecimal.ROUND_DOWN);
6 System.out.println(bd1.toString());
7 //始终向上进位
8 BigDecimal bd2 = bd.setScale(decimalPlaces, BigDecimal.ROUND_UP);
9 System.out.println(bd2.toString());
10 BigDecimal bd3 = new BigDecimal(3.14159);
11 //四舍五入
12 bd3 = bd3.setScale(3, BigDecimal.ROUND_HALF_UP);
13 System.out.println(bd3.toString());
14 }
15 /* 输出结果如下:
16 123456789.01
17 123456789.02
18 3.142
19 */

    2.    大整型对象(BigInteger):
    BigInteger和BigDecimal相比,大部分的功能是相同的,主要的差异为BigInteger仅仅表示大整数的封装,而不能表示浮点数,与此同时,BigInteger还提供了大量的位操作运算,这个和C++中的BitSet非常类似。如果我们的在应用中只是需要大整数,那么应该首先该类,而不是BigDecimal,如果我们的应用逻辑中有多于64种状态(long表示64bits)的情况,可以考虑用BigInteger的位操作功能。
    1)    基本的数学运算和数学函数应用:

 1     public static void main(String args[]) {
2 BigInteger bi1 = new BigInteger("1234567890123456890");
3 BigInteger bi2 = BigInteger.valueOf(123L);
4 System.out.printf("bi1 = %s after added\n",bi1.add(bi2));
5 System.out.printf("bi1 = %s after multiply\n",bi1.multiply(bi2));
6 System.out.printf("bi1 = %s after subtract\n",bi1.subtract(bi2));
7 System.out.printf("bi1 = %s after divide\n",bi1.divide(bi2));
8 System.out.printf("bi1 = %s after negate\n",bi1.negate());
9 int exponent = 2;
10 System.out.printf("bi1 = %s after pow\n",bi1.pow(exponent));
11 }
12 /* 输出结果如下:
13 bi1 = 1234567890123457013 after added
14 bi1 = 151851850485185197470 after multiply
15 bi1 = 1234567890123456767 after subtract
16 bi1 = 10037137318076885 after divide
17 bi1 = -1234567890123456890 after negate
18 bi1 = 1524157875323883924401765803688472100 after pow
19 */

    2)    将BigInteger的值转换为各种进制的字符串表示:

 1     public static void main(String args[]) {
2 BigInteger number = new BigInteger("2008");
3 System.out.println("Number = " + number);
4 System.out.println("Binary = " + number.toString(2));
5 System.out.println("Octal = " + number.toString(8));
6 System.out.println("Hexadecimal = " + number.toString(16));
7 number = new BigInteger("FF", 16);
8 System.out.println("Number = " + number);
9 System.out.println("Number = " + number.toString(16));
10 }
11 /* 输出结果如下:
12 Number = 2008
13 Binary = 11111011000
14 Octal = 3730
15 Hexadecimal = 7d8
16 Number = 255
17 Number = ff
18 */

    3)    从字符串构造各种进制的BigInteger对象:

 1     public static void main(String args[]) {
2 BigInteger bi = new BigInteger("120ff0", 16);
3 Integer ii = Integer.valueOf("120ff0", 16);
4 if (bi.intValue() == ii.intValue())
5 System.out.println("bi.intValue == ii.intValue");
6 System.out.println("int i = " + bi.intValue());
7
8 BigInteger bi2 = new BigInteger("100100100111111110000", 2);
9 System.out.println(bi2.intValue());
10 }
11 /* 输出结果如下:
12 bi.intValue == ii.intValue
13 int i = 1183728
14 1200112
15 */

    4)    位操作:

 1     public static void main(String args[]) {
2 byte[] bytes = new byte[] { 0x1, 0x00, 0x00 };
3 BigInteger bi = new BigInteger(bytes);
4 //相当于 & (~)的位运算。
5 System.out.println("andNot = " + bi.andNot(bi));
6 //相当于 | 的位运算
7 BigInteger bi2 = new BigInteger(bytes);
8 System.out.println("or = " + bi2.or(bi2));
9 //相当于 ~ 的位运算
10 BigInteger bi3 = new BigInteger(bytes);
11 System.out.println("not = " + bi3.not());
12 //相当于 & 的位运算
13 BigInteger bi4 = new BigInteger(bytes);
14 System.out.println("and = " + bi4.and(bi4));
15 //相当于 ^ 的位运算
16 BigInteger bi5 = new BigInteger(bytes);
17 System.out.println("xor = " + bi5.xor(bi5));
18 }
19 /* 输出结果如下:
20 andNot = 0
21 or = 65536
22 not = -65537
23 and = 65536
24 xor = 0
25 */

    5)    移位运算:

 1     public static void main(String args[]) {
2 byte[] bytes = new byte[] { 0x1, 0x00, 0x00 };
3 BigInteger bi = new BigInteger(bytes);
4 System.out.println(bi);
5 //右移一位
6 System.out.println("after shift right is " + bi.shiftRight(1));
7 //左移3位
8 System.out.println("after shift left is " + bi.shiftLeft(3));
9 //翻转第三位,既如果第三位(0 based)为0,则翻转为1,反之翻转为0.
10 //翻转之前:10000000000000000
11 //翻转之后:10000000000001000
12 bi = bi.flipBit(3);
13 System.out.println("after flip is " + bi);
14 //将第三位的bit清0
15 //clear之前:10000000000001000
16 //clear之后:10000000000000000
17 bi = bi.clearBit(3);
18 System.out.println("after clear is " + bi);
19 //将第三位设置为1
20 //set之前:10000000000000000
21 //set之后:10000000000001000
22 bi = bi.setBit(3);
23 System.out.println("after set is " + bi);
24 System.out.println("The binary result for bi is " + bi.toString(2));
25 System.out.println("The test result for BIT 2 is " + bi.testBit(2));
26 System.out.println("The test result for BIT 3 is " + bi.testBit(3));
27 }
28 /* 输出结果如下:
29 65536
30 after shift right is 32768
31 after shift left is 524288
32 after flip is 65544
33 after clear is 65536
34 after set is 65544
35 The binary result for bi is 10000000000001000
36 The test result for BIT 2 is false
37 The test result for BIT 3 is true
38 */

    3.    时区:
    如果你的产品面向全世界的每一个角落,或者说你接到外包项目可能来自多个不同的国家,那么你的程序将会面临时区问题。
    1)    基于不同时区设置本地时区的Calendar:

 1     public static void main(String args[]) {
2 //获取基于日本时区的Calendar对象。
3 Calendar japanCal = new GregorianCalendar(TimeZone.getTimeZone("Japan"));
4 japanCal.set(Calendar.HOUR_OF_DAY, 10); // 0..23
5 japanCal.set(Calendar.MINUTE, 0);
6 japanCal.set(Calendar.SECOND, 0);
7 //本地时区为北京时区
8 Calendar local = new GregorianCalendar();
9 local.setTimeInMillis(japanCal.getTimeInMillis());
10 int hour = local.get(Calendar.HOUR);
11 int minutes = local.get(Calendar.MINUTE);
12 int seconds = local.get(Calendar.SECOND);
13 System.out.println("Hours = " + hour + "\tMinutes = " + minutes
14 + "\tSeconds = " + seconds);
15 }
16 /* 输出结果如下:
17 Hours = 9 Minutes = 0 Seconds = 0
18 */

    和预想的一样,我们通过日本时区设置时间后,在通过该Calendar来设置本地时区的Calendar,结果是得到正确的本地时间,换句话说,时区参与了时间的计算。因此可以说,Calendar对象在生成小时部分的时间时,会结合当时的时间和本地的时区来构造该部分,当时区切换时,Calendar会根据初始的时区、初始的时间和当前的时区来进行推算并给出结果。
    2)    获取本地时区和所有可用时区:

 1     public static void main(String args[]) {
2 //获取本地时区
3 Calendar now = Calendar.getInstance();
4 TimeZone timeZone = now.getTimeZone();
5 System.out.println("Current TimeZone is : " + timeZone.getDisplayName());
6 //获取系统当前所有可用的时区
7 String[] availableTimezones = TimeZone.getAvailableIDs();
8 for (String timezone : availableTimezones) {
9 System.out.println("Timezone ID = " + timezone);
10 }
11 }
12 /* 输出结果如下:
13 Current TimeZone is : 中国标准时间
14 Timezone ID = Etc/GMT+12
15 Timezone ID = Etc/GMT+11
16 ... ...
17 */

    4.    格式化:
    1)    日期时间的格式化:
    这里先列出日期和时间格式化的suffix:
    Suffix    Replaced By
    a         Abbreviated weekday name
    A         Full weekday name
    b         Abbreviated month name
    B         Full month name
    c         Standard date and time string formatted as day month date hh::mm:ss tzone year
    C         First two digits of year
    d         Day of month as a decimal (01-31)
    D         month/day/year
    e         Day of month as a decimal (1-31)
    F         year-month-day
    h         Abbreviated month name
    H         Hour (00 to 23)
    I         Hour (01 to 12)
    j         Day of year as a decimal (001 to 366)
    k         Hour (0 to 23)
    l         Hour (1 to 12)
    L         Millisecond (000 to 999)
    m         Month as decimal (01 to 13)
    M         Minute as decimal (00 to 59)
    N         Nanosecond (000000000 to 999999999)
    p         Locale equivalent of AM or PM in lowercase
    Q         Milliseconds from 1/1/1970
    r         hh:mm:ss (12-hour format)
    R         hh:mm (24-hour format)
    S         Seconds (00 to 60)
    s         Seconds from 1/1/1970 UTC
    T         hh:mm:ss (24-hour format)
    y         Year in decimal without century (00 to 99)
    Y         Year in decimal including century (0001 to 9999)
    z         Offset from UTC
    Z         Time zone name

 1     public static void main(String args[])  {
2 Formatter fmt = new Formatter();
3 Calendar cal = Calendar.getInstance();
4 //这里的<符号表示%tB取后面格式化参数的index等同于其前面的%te,均为1$,既cal。
5 fmt.format("Today is day %te of %<tB, %<tY\n", cal);
6 fmt.format("Default locale: %tc\n", cal);
7 fmt.format(Locale.GERMAN, "For Locale.GERMAN: %tc\n", cal);
8 fmt.format(Locale.ITALY, "For Locale.ITALY: %tc\n", cal);
9 fmt.format(Locale.FRANCE, "For Locale.FRANCE: %tc\n", cal);
10 //1$表示取格式化参数列表中的第一个作为格式化替换符。
11 fmt.format("Hour and Minute: %tl:%1$tM %1$Tp\n", cal);
12 //区分%t和%T的差异。
13 fmt.format(Locale.US,"Time and date in lowercase: %tc\n", cal);
14 fmt.format(Locale.US,"Time and date in uppercase: %Tc\n", cal);
15 //显示全名日期格式
16 fmt.format("Long date format: %tA %1$tB %1$td, %1$tY\n", cal);
17 //显示最短日期格式
18 fmt.format("Short date format: %tD\n", cal);
19 //显示24小时时间格式
20 fmt.format("Time using 24-hour clock: %tT\n", cal);
21 //显示12小时时间格式
22 fmt.format("Time using 12-hour clock: %tr\n", cal);
23 System.out.println(fmt);
24 }
25 /* 输出结果如下:
26 Today is day 6 of 九月, 2011
27 Default locale: 星期二 九月 06 23:00:15 CST 2011
28 For Locale.GERMAN: Di Sep 06 23:00:15 CST 2011
29 For Locale.ITALY: mar set 06 23:00:15 CST 2011
30 For Locale.FRANCE: mar. sept. 06 23:00:15 CST 2011
31 Hour and Minute: 11:00 下午
32 Time and date in lowercase: Tue Sep 06 23:00:15 CST 2011
33 Time and date in uppercase: TUE SEP 06 23:00:15 CST 2011
34 Long date format: 星期二 九月 06, 2011
35 Short date format: 09/06/11
36 Time using 24-hour clock: 23:00:15
37 Time using 12-hour clock: 11:00:15 下午
38 */

    2)    字符串格式化形式:

 1     public static void main(String args[]) {
2 Formatter fmt = new Formatter();
3 //-12表示左对齐,如果不足12个字符宽度则右侧补0,12则完全相反,既右对齐,
4 //如果不足12个字符宽度则左侧补0。
5 fmt.format("%-12s %12s\n", "Source", "Loss");
6 fmt.format("%-12s %,12d\n", "Retail", 1232675);
7 fmt.format("Formatting %s is easy %d %f\n", "with Java", 10, 98.6);
8 //两个百分号%%表示转义后的百分号。
9 fmt.format("Copying file\nTransfer is %d%% complete", 88);
10 System.out.println(fmt);
11 }
12 /* 输出结果如下:
13 Source Loss
14 Retail 1,232,675
15 Formatting with Java is easy 10 98.600000
16 Copying file
17 Transfer is 88% complete
18 */

    3)    数值格式化:

 1     public static void main(String args[]) {
2 double data[] = { 12.3, 45.6, -7.89, -1.0, 1.01 };
3 Formatter fmt = new Formatter();
4 fmt.format("%12s %12s\n", "Value", "Cube Root");
5 //这里的12.4表示为width.precision,既宽度.精度
6 //如果转换为字符串后的宽度不足12,则左侧补0。
7 for (double v : data)
8 fmt.format("%12.4f %12.4f\n", v, Math.cbrt(v));
9 //如果没有指定宽度,则为实际宽度。
10 fmt.format("Default positive and negative format: %.2f %.2f\n", 423.78,-505.09);
11 //注意+和(的使用方式。
12 fmt.format("With + and parentheses: %+.2f %(.2f\n", 423.78, -505.09);
13 //这里用到缺省精度。
14 fmt.format("Default precision: %f\n", 10.0 / 3.0);
15 fmt.format("Two decimal digits: %.2f\n", 10.0 / 3.0);
16 //注意三者之间的差异。
17 fmt.format("|%f|\n|%12f|\n|%012f|", 10.12345, 10.12345, 10.12345);
18 System.out.println(fmt);
19 }
20 /* 输出结果如下:
21 Value Cube Root
22 12.3000 2.3084
23 45.6000 3.5726
24 -7.8900 -1.9908
25 -1.0000 -1.0000
26 1.0100 1.0033
27 Default positive and negative format: 423.78 -505.09
28 With + and parentheses: +423.78 (505.09)
29 Default precision: 3.333333
30 Two decimal digits: 3.33
31 |10.123450|
32 | 10.123450|
33 |00010.123450|
34 */

    5.    Runtime:
    通过Runtime可以获得更多关于JVM的信息,以及更多和系统之间的交互。

 1     public static void main(String args[]) throws IOException {
2 // 以下的返回值均以字节为单位。
3 // 获取JVM中空闲堆的大小
4 long heapFreeSize = Runtime.getRuntime().freeMemory();
5 System.out.println(heapFreeSize);
6 // 获取JVM最大可分配堆的大小。
7 long heapMaxSize = Runtime.getRuntime().maxMemory();
8 System.out.println(heapMaxSize);
9 // 当前JVM总共可用的堆空间。
10 long heapSize = Runtime.getRuntime().totalMemory();
11 System.out.println(heapSize);
12 //获取当前主机的cpu数量
13 int nrOfProcessors = Runtime.getRuntime().availableProcessors();
14 System.out.println("Number of processors available to the Java Virtual Machine: "
15 + nrOfProcessors);
16 // 通过Runtime运行外部程序,同时可以获取子进程的输出
17 // 作为当前进程的输入。
18 String[] commands = new String[] { "ls", "*" };
19 Process child = Runtime.getRuntime().exec(commands);
20 InputStream pin = child.getInputStream();
21 int c;
22 while ((c = pin.read()) != -1) {
23 System.out.println((char) c);
24 }
25 pin.close();
26 try {
27 //阻塞等待直到子进程退出,并获取退出码。
28 System.out.println("Exit status = " + child.waitFor());
29 } catch (InterruptedException e) {
30 e.printStackTrace();
31 }
32 System.out.println("Over.");
33 //注册一个钩子,在虚拟机退出的时候会调用run方法,以完成一些必须的资源释放操作。
34 Runtime.getRuntime().addShutdownHook(new Thread() {
35 public void run() {
36 System.out.println("Do shutdown work ...");
37 }
38 });
39 }
40 /* 输出结果如下:
41 15840832
42 259522560
43 16252928
44 Number of processors available to the Java Virtual Machine: 1
45 Over.
46 Do shutdown work ...
47 */

    6.    TimeUnit:
    一个表示时间跨度的对象,在很多其他语言的类库中均有类似这样的工具类,如C#的TimeSpan,他们的共同特征就是在该类和表示日期的对象之间提供了完美的结合。

 1     public class MyTest {
2 public static long getDifference(Calendar a, Calendar b, TimeUnit units) {
3 return units.convert(b.getTimeInMillis() - a.getTimeInMillis(),
4 TimeUnit.MILLISECONDS);
5 }
6
7 public static void main(String args[]) {
8 Calendar first = Calendar.getInstance();
9 first.set(2008, Calendar.AUGUST, 1);
10 Calendar second = Calendar.getInstance();
11 System.out.println(getDifference(first, second, TimeUnit.DAYS)
12 + " day(s) between ");
13 }
14 }
15 /* 输出结果如下:
16 1132 day(s) between
17 */

    7.    数学相关函数:
    1)    三角函数:

 1     public static void main(String args[]) {
2 double degrees = 45.0;
3 //去弧度
4 double radians = Math.toRadians(degrees);
5 System.out.println("The value of pi is " + Math.PI);
6 System.out.println("The sine of " + degrees + " is "
7 + Math.sin(radians));
8 System.out.println("The cosine of " + degrees + " is "
9 + Math.cos(radians));
10 System.out.println("The tangent of " + degrees + " is "
11 + Math.tan(radians));
12 System.out.println("The arc sine of " + Math.sin(radians) + " is "
13 + Math.toDegrees(Math.asin(Math.sin(radians))) + " degrees");
14 System.out.println("The arc cosine of " + Math.cos(radians) + " is "
15 + Math.toDegrees(Math.acos(Math.cos(radians))) + " degrees");
16 System.out.println("The arc tangent of " + Math.tan(radians) + " is "
17 + Math.toDegrees(Math.atan(Math.tan(radians))) + " degrees");
18 }
19 /* 输出结果如下:
20 The value of pi is 3.141592653589793
21 The sine of 45.0 is 0.8509035245341184
22 The cosine of 45.0 is 0.7071067811865476
23 The tangent of 45.0 is 0.9999999999999999
24 The arc sine of 0.7071067811865475 is 44.99999999999999 degrees
25 The arc cosine of 0.7071067811865476 is 45.0 degrees
26 The arc tangent of 0.9999999999999999 is 45.0 degrees
27 */

    2)    原始浮点类型的相等性比较:

 1     public class MyTest {
2 public static boolean equals(double v1,double v2) {
3 return Math.abs(v1 - v2) < 1.0E-10;
4 }
5
6 public static void main(String args[]) {
7 double a = 9.33333333333000;
8 double b = 9.33333333333333;
9
10 if (equals(a, b))
11 System.out.println("double values are equal");
12 else
13 System.out.println("double values are not equal");
14
15 Double da = a;
16 Double db = b;
17 if (da.equals(b))
18 System.out.println("Double values are equal");
19 else
20 System.out.println("Double values are not equal");
21
22 }
23 }
24 /* 输出结果如下:
25 double values are equal
26 Double values are not equal
27 */

    在Double中比较两个对象的相等性时,由于是基于位的严格比较,因此判断结果是不相等的。然而在很多精度要求并不高的应用中,如果两个浮点数之间的差值小于一定的精度时,可以视为相等的浮点数。再者就是直接使用原始类型的double进行比较时效率会远远高于包装对象的计算。
    3)    基本的数学函数:

 1     public static void main(String args[]) {
2 // 1. 平方根的计算
3 double dd = 9.0;
4 System.out.println("Math.sqrt(9.0) = " + Math.sqrt(dd));
5 // 2. 幂次计算
6 System.out.println("pow(9.0, 0.5) = " + Math.pow(9.0, 0.5));
7 // 3. 对数计算
8 double num = 100.0d;
9 // 自然对数
10 double loge = Math.log(num);
11 System.out.println("log base e = " + loge);
12 // 常用对数
13 double log10 = Math.log(num) / Math.log(10.0);
14 System.out.println("log base 10 = " + log10);
15 // 返回以e为底数的loge幂次,相当于反自然对数
16 double aloge = Math.exp(loge);
17 System.out.println("antilog of log base e = " + aloge);
18 // 反常用对数
19 double alog10 = Math.pow(10.0, log10);
20 System.out.println("anitlog of log base 10 = " + alog10);
21 // 4. 基本数学计算
22 double aNumber = -191.235;
23 //绝对值
24 System.out.println("The absolute value of " + aNumber + " is "
25 + Math.abs(aNumber));
26 //取高于aNumber的最小整数
27 System.out.println("The ceiling of " + aNumber + " is "
28 + Math.ceil(aNumber));
29 //取低于aNumber的最大整数
30 System.out.println("The floor of " + aNumber + " is "
31 + Math.floor(aNumber));
32 //返回距离aNumber最近的整数,如果aNumber = 191.666,则返回192.
33 System.out.println("The rint of " + aNumber + " is "
34 + Math.rint(aNumber));
35 //5. 最值比较
36 double firstDouble = 45.875;
37 double secondDouble = 54.375;
38 System.out.println("The minimum value is: "
39 + Math.min(firstDouble, secondDouble));
40 //6. 浮点进位到整数
41 double d1 = 0.49d;
42 double d2 = 0.5d;
43 System.out.println("d1 = 0.49 is " + Math.round(d1));
44 System.out.println("d2 = 0.5 is " + Math.round(d2));
45 }
46 /* 输出结果如下:
47 Math.sqrt(9.0) = 3.0
48 pow(9.0, 0.5) = 3.0
49 log base e = 4.605170185988092
50 log base 10 = 2.0
51 antilog of log base e = 100.00000000000004
52 anitlog of log base 10 = 100.0
53 The absolute value of -191.235 is 191.235
54 The ceiling of -191.235 is -191.0
55 The floor of -191.235 is -192.0
56 The rint of -191.235 is -191.0
57 The minimum value is: 45.875
58 d1 = 0.49 is 0
59 d2 = 0.5 is 1
60 */

    8.    System 工具类:
    我们在开发中用到System类的最常用方法是System.currentTimeMillis(),用于获取当前的时间,然后再执行一段测试效率的代码,之后再一次执行该方法并减去之前调用该方法获得的时间值,计算的结果就是中间测试代码消耗的时间(毫秒)。事实上,如果我们充分了解System,他会给我们的开发带来更大的帮助,见如下代码:

 1     public class MyTest {
2 private static void getSystemEnv() {
3 // 1. 获取系统当前的环境变量
4 Map map = System.getenv();
5 Iterator iterator = map.keySet().iterator();
6 while (iterator.hasNext()) {
7 String key = (String) iterator.next();
8 String value = (String) map.get(key);
9 System.out.println(key + " = " + value);
10 }
11 }
12
13 private static void getJavaEnv() {
14 // 2. 获取Java自身的环境变量
15 Properties props = System.getProperties();
16 Iterator iterator = props.entrySet().iterator();
17 while (iterator.hasNext()) {
18 Map.Entry entry = (Map.Entry) iterator.next();
19 System.out.println(entry.getKey() + " --- " + entry.getValue());
20 }
21 }
22
23 private static void getSpecifiedSystemEnv() {
24 // 3. 获取指定的系统环境变量值
25 // 3.1 用户主目录
26 System.out.println("Home Path: " + System.getProperty("user.home"));
27 // 3.2 操作系统的名称
28 System.out.println("Name: " + System.getProperty("os.name"));
29 // 3.3 操作系统的版本
30 System.out.println("Version: " + System.getProperty("os.version"));
31 // 3.4 操作系统的体系结构
32 System.out.println("Architecture: " + System.getProperty("os.arch"));
33 // 3.5 获取当前执行目录
34 System.out.println("Current Directory: " + System.getProperty("user.dir"));
35 // 3.6 获取文件分隔符
36 System.out.println("File Separator: " + System.getProperty("file.separator"));
37 // 3.7 获取Path环境变量中各个路径间的分隔符
38 System.out.println("Path Separator = " + System.getProperty("path.separator"));
39 // 3.8 获取Java的主目录
40 System.out.println("Java Home = " + System.getProperty("java.home"));
41 // 3.9 获取操作系统的临时目录
42 System.out.println("OS current temporary directory is "
43 + System.getProperty("java.io.tmpdir"));
44 // 3.10获取JRE版本
45 String version = System.getProperty("java.version");
46 char minor = version.charAt(2);
47 char point = version.charAt(4);
48 if (minor < '4' || point < '1') {
49 System.out.println("Your JRE version is higher than 1.4.");
50 }
51 System.out.println("JRE Version = " + System.getProperty("java.version"));
52 // 3.11获取当前用户
53 System.out.println("username = " + System.getProperty("user.name"));
54 // 3.12获取系统的Path环境变量
55 System.out.println("System.getenv(\"PATH\") = " + System.getenv("PATH"));
56 }
57
58 public static void main(String args[]) {
59 getSystemEnv();
60 getJavaEnv();
61 getSpecifiedSystemEnv();
62 }
63 }

    运行以后看看自己的结果吧。

你可能感兴趣的:(java)