目录
I. Introduction
对任何程序来说,数据都是最基础的东西。无论你是想做销售系统,或者财务系统,乃至于学校成天要你做的图书管理系统(比如武汉理工),没有数据的支持,都是镜花水月。
Java拥有几种常见的数据类型用来表示整数,浮点数,布尔值以及字符等。注意,Java为了跨平台兼容已经对数据类型的大小做出详细的规定,而不是像C语言那样任由编译器来决定。
更正:boolean官方文档没有明确定义,依赖于JVM具体实现。逻辑上理解是占用 1 位,但是实际中会考虑计算机高效存储因素。
[来源: JavaGuide/Java基础知识 · Snailclimb/JavaGuide (github.com)]
类型 | 包装器 | 位数 | 内容 | 默认值 |
---|---|---|---|---|
byte | Byte | 8 | 带符号整数 | 0 |
int | Integer | 32 | 带符号整数 | 0 |
short | Short | 16 | 带符号整数 | 0 |
long | Long | 64 | 带符号整数 | 0L |
float | Float | 32 | IEEE-754 浮点数 | 0f |
double | Double | 64 | IEEE-754 浮点数 | 0d |
char | Char | 16 | 无符号整数 | 'u0000' |
boolean | Boolean | 1 | 布尔值 | false |
本章节绝大多数内容来源于 Java Cookbook, Third Edition,感谢 Ian F. Darwin 的内容。
II. Content
Trick 1. 检查字符串是否可以有效地转化为数字
你需要确定字符串 s 是否可以转化为数字 x,如果可以,进行转化。
解决方法:
用上正确的包装类以及异常处理机制。包装类中有一个parseXXX方法,可以很方便地把一个字符串解析成数字。
代码:
public static void main(String[] argv) {
String aNumber = argv[0]; // not argv[1]
double result;
try {
result = Double.parseDouble(aNumber);
System.out.println("Number is " + result);
} catch (NumberFormatException exc) {
System.out.println("Invalid number " + aNumber);
return;
}
}
补充:
如果你的数字类型比较特殊,可以用正则表达式解决。
Trick 2. 将一个较大的数据类型存储在较小的类型中
你希望将一个 long 的数据存储在 short 或者 int 。
解决方法:
强制类型转化。
代码:
long old_one = 150;
short new_one = (short) old_one;
补充:
// 错误写法
float f = 3.0;
// 等价于
double tmp = 3.0;
float f = tmp;
// 正确写法
float f = 3.0f; // or just 3f
double f = 3.0;
float f = (float)3.0;
float f = 3;
// int 转化为short, char, byte也会有这种错误。
Trick 3. 两个浮点数的比较
浮动数的运算其实是有一定误差的,这里有一个很经典的例子
System.out.println(1.0F-0.9F==0.9F-0.8F); // false
所以,我们一般不会直接比较两个浮点数。当然,你也许会认为用包装类的equals方法是可行的。很遗憾,我测试了一下,还是不行。我推荐的办法就是把误差考虑进去,比如自己设计一个equals的函数。
private static boolean equals(double a, double b, double eps){
return Math.abs(a,b)<eps;
}
Trick 4. 求浮点数的近似数
如果用强制类型转化,Java会直接把浮点数的小数部分全部丢弃掉。比如,3.999999转化成int 或者 long 就只会是3,而不是4。Math.round() 可以很好的解决问题。如果你的参数是一个 double ,这个函数返回一个 long;如果参数是float,则会返回 int。
Trick 5. 格式化输出数字
使用 NumberFormat 类来解决问题。
Java并不原生的提供C语言那样的printf / scanf。尽管这样的设计让输入输出更加灵活,但是想要规整地输出数字就麻烦许多了。当然,Java已经为我们考虑好了这个问题,java.text 就包含了一系列地格式化输出地方案,齐全程度超乎你想象。下面是参考代码:
import java.text.NumberFormat;
public class main {
/** A number to format */
public static final double data[] = { 0, 1, 22d / 7, 100.2345678 };
/** The main (and only) method in this class. */
public static void main(String[] args) {
// Get a format instance
NumberFormat form = NumberFormat.getInstance();
// Set it to look like 999.99[99]
form.setMinimumIntegerDigits(3);
form.setMinimumFractionDigits(2);
form.setMaximumFractionDigits(4);
// Now print using it.
for (int i = 0; i < data.length; i++)
System.out.println(data[i] + "\tformats as " + form.format(data[i]));
}
}
// Java Cookbook 3rd Edition 2014
输出:
0.0 formats as 000.00
1.0 formats as 001.00
3.142857142857143 formats as 003.1429
100.2345678 formats as 100.2346
Trick 6. 进制转换
如果你需要将2进制转化为8进制,16进制等等,你可以尝试使用 Integer.parseInt(String input, int radix) 与 Integer.toString(int input, int radix)。这两个方法都可以很方便地进行进制转化。
参考代码:
public static void main(String[] args) {
// Get a format instance
String input = "101010";
for (int radix : new int[] { 2, 8, 10, 16, 36 }) {
System.out.print(input + " in base " + radix + " is " + Integer.valueOf(input, radix) + "; ");
int i = 42;
System.out.println(i + " formatted in base " + radix + " is " + Integer.toString(i, radix));
}
}
输出:
101010 in base 2 is 42; 42 formatted in base 2 is 101010
101010 in base 8 is 33288; 42 formatted in base 8 is 52
101010 in base 10 is 101010; 42 formatted in base 10 is 42
101010 in base 16 is 1052688; 42 formatted in base 16 is 2a
101010 in base 36 is 60512868; 42 formatted in base 36 is 16
Trick 7. 大数处理
待