== 和 equals
- 当基本数据类型的包装类使用
=时,会使用XXX.valueOf(),会走 cache- 如果在 cache 外,那么进行
==时,即使值一样,引用也绝对不一样 - 这也是为什么基本数据类型只能用
==比较值,而引用数据类型只能用equals比较值
- 如果在 cache 外,那么进行
测试
public static void main(String[] args) {/*== 比较地址*/Integer a = 2;Integer b = 2;Integer c = new Integer(2);System.out.println(a == b); // trueSystem.out.println(a == c); // falseInteger aa = 150; // 使用 Integer.valueOf(150)Integer bb = 150;Integer cc = new Integer(150);System.out.println(aa == bb); // falseSystem.out.println(aa == cc); // falseInteger aaa = 150;System.out.println(aaa == 150); // true, 装箱拆箱,比较值而不是地址}
Integer和Long
IntegerCache
- 直接赋值和
Integer.valueOf()会使用到缓存 看源码
String integerCacheHighPropValue=sun.misc.VM.getSavedProperty(“java.lang.Integer.IntegerCache.high”)
;可以带上参数
-XX:AutoBoxCacheMax=xxx来 设置缓存数值上限,即 [-128~xxx]// IntegerCacheprivate static class IntegerCache {static final int low = -128;static final int high;static final Integer cache[];static {// high value may be configured by propertyint h = 127;String integerCacheHighPropValue =// 可以通过 -XX:AutoBoxCacheMax=xxx 设置sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");if (integerCacheHighPropValue != null) {try {int i = parseInt(integerCacheHighPropValue);i = Math.max(i, 127);// Maximum array size is Integer.MAX_VALUEh = Math.min(i, Integer.MAX_VALUE - (-low) -1);} catch( NumberFormatException nfe) {// If the property cannot be parsed into an int, ignore it.}}high = h;cache = new Integer[(high - low) + 1];int j = low;for(int k = 0; k < cache.length; k++)cache[k] = new Integer(j++);// range [-128, 127] must be interned (JLS7 5.1.7)assert IntegerCache.high >= 127;}private IntegerCache() {}}
建议使用
valueOf而不是parseInteger
LongCache
直接赋值和
Long.valueOf()会使用到缓存// LongCacheprivate static class LongCache {private LongCache(){}// -128~127 的长度, +1 是因为有0static final Long cache[] = new Long[-(-128) + 127 + 1];static {for(int i = 0; i < cache.length; i++)// 缓存 -128~127cache[i] = new Long(i - 128);}}
建议使用
valueOf而不是parseLong
BigDecimal
初始化
- 使用
BigDecimal表示和计算浮点数,且务必使用字符串的构造方法来初始化BigDecimal - 如果一定要用
Double来初始化BigDecimal的话,可以使用BigDecimal#valueOf()- scale 表示小数点右边的位数,而 precision 表示精度,也就是有效数字的长度。
- scale 可能会变化,比如
BigDecimal#multiply,会让 scale 相加
格式化
- 浮点数的字符串格式化也要通过 BigDecimal 进行 ```java BigDecimal num1 = new BigDecimal(“3.35”); // 指定格式方式 BigDecimal num2 = num1.setScale(1, BigDecimal.ROUND_DOWN); System.out.println(num2);
BigDecimal num3 = num1.setScale(1, BigDecimal.ROUND_HALF_UP); System.out.println(num3); ```
比较
BigDecimal#equals()比较的是BigDecimal的value和scale- 如果要用于比较,可以用
BigDecimal#compareTo()
- 如果要用于比较,可以用
BigDecimal存储进 HashMap 有问题,因为后者是比较equals- 使用 TreeMap 代替,后者使用
compareTo进行比较 - 将元素使用
BigDecimal#stripTrailingZeros()将尾部的0去除,就可以存储到 HashMap 中了
- 使用 TreeMap 代替,后者使用
溢出
- 使用
Math类的addExact、subtractExact等 xxExact 方法进行数值运算,这些方法可以在数值溢出时主动抛出异常ArithmeticException - 使用
BigInteger,比如在将计算结果转换一个Long变量的话,可以使用BigIntegr#longValueExact()方法,在转换出现溢出时,同样会抛出 ArithmeticException
