常用类

76 阅读3分钟

Object

Object是所类的父类。

包装类

从性能上考虑,把常用数据存储到缓存区域,使用时不需要每次都创建新的对象,可以提高性能。
ByteShortIntegerLong:缓存范围[-128, 127];
Character: 缓存范围[0, 127];

BigDecimal

floatdouble都不能表示精确的小数,使用BigDecimal类可以解决该问题,BigDecimal用于处理金钱或任意精度要求高的数据。

基本运算

// 使用double类型
        System.out.println(0.09 + 0.01); // 0.09999999999999999
​
        // 使用BigDecimal类型double类型的构造器
        BigDecimal num1 = new BigDecimal(0.09);
        BigDecimal num2 = new BigDecimal(0.01);
        System.out.println(num1.add(num2)); // 0.09999999999999999687749774324174723005853593349456787109375
​
        // 使用BigDecimal类型String类型的构造器
        BigDecimal num3 = new BigDecimal("0.09");
        BigDecimal num4 = new BigDecimal("0.01");
        System.out.println(num3.add(num4)); // 0.10

精度控制和除不尽问题

public static void main(String[] args) {
    BigDecimal num1 = new BigDecimal("10.0");
    BigDecimal num2 = new BigDecimal("3.0");
​
    // 1. 保留位数和精度控制
    // RoundingMode 舍入模式
    // RoundingMode.HALF_UP   四舍五入
    // RoundingMode.HALF_DOWN 四舍六入
    BigDecimal r1 = num1.multiply(num2).setScale(2, RoundingMode.HALF_UP);
    System.out.println("r1 = " + r1);
​
    // 2. 除不尽问题
    // java.lang.ArithmeticException
    // Non-terminating decimal expansion; no exact representable decimal result.
    // 报错原因:除不尽(3.333333333...333...)
    BigDecimal r2 = num1.divide(num2, 3,RoundingMode.HALF_UP);
    System.out.println("r2 = " + r2);
}

上述代码分别表示乘法和除法按照四舍五入方式保留两位小数。

String为什么是不可变的?

1. String类中使用final关键字修饰字符数组来保存字符串,private final char[] value, 所以String对象是不可变的。
2. String类也是用final修饰的,String不能被继承,所以String中的方法是不能被重写的
3. String类中只提供了可读方法。    

String、StringBuilder、StringBuffer的区别

1. 可变性:
String类中使用final关键字修饰字符数组保存字符串,private final char[] value; String类也是final修饰,String不能被继承,String类中的方法不能被覆盖;String类中只提供了可读方法,所以String对象是不可变的。而StringBuilder和StringBuffer都继承自AbstractStringBuilder类,在AbstractStringBuilder中也是使用字符数组保存字符串char[] value但是没有用final关键字修饰,所以这两种对象都是可变的。
​
2. 线程安全性
StringBuilder对方法加了同步锁或者调用的方法加了同步锁,所以是线程安全的。StringBuilder并没有对方法进行加同步锁,所以是非线程安全的。
​
3. 性能
每次对String类型进行改变的时候,都会生成一个新的String对象,然后将指针指向新的String对象。StringBuffer每次都会对StringBuffer对象本身进行操作,而不是生成新的对象并改变对象引用。相同情况下使用StringBuilder相比使用StringBuffer仅能获得10%~15%左右的性能提升,但却要冒多线程不安全的风险。
​
对于三者使用的总结:
1. 操作少量的数据:适用String
2. 单线程操作字符串缓冲区下操作大量数据:适用StringBuilder
3. 多线程操作字符串缓冲区下操作大量数据:适用stringBuffer

对象比较

Comparable
comparable接口实际上是出自java.lang包,它有一个comparaTo(Object obj)方法来排序。
Comparator
comparator接口实际上是出自java.util包它有一个compare(Object obj1, Object obj2)方法来排序

一般我们需要对一个集合使用自定义排序时,我们就要重写compareTo()方法或compare()方法,当我们需要对某一个集合实现两种排序方式,比如一个song对象中的歌名和歌手名分别采用一种排序方法的话,我们可以重写compareTo()方法和使用自制的Comparator方法或者以两个Comparator来实现歌名排序和歌星名排序,第二种代表我们只能使用两个参数版的Collections.sort()