Java基础 | 常用类

Java基础 | 常用类

日期时间相关

时间戳

从 1970.01.01 00:00:00 至今的毫秒数,通常用来做差计算程序执行耗时

  • System 类中的 public static long currentTimeMillis() 方法可以返回时间戳

Date 类

Date类有两个,一个是 java.util.Date,一个是其子类,java.sql.Date(对应数据库中的日期变量)

  • 构造器
Date()
// 创建一个对应当前时间的 Date 对象
Date(long time)
// 创建一个对应指定 time 时间戳的 Date 对象 或 java.sql.Date 类的对象
  • 方法
String toString();
// 显示当前 Date 对象的年、月、日、时、分、秒、星期、时区等信息
long getTime();
// 获取当前 Date 对象对应的时间戳  

SimpleDateFormat 类

  • java.text.SimpleDateFormat 类是一个格式化和解析日期的类,其格式化与解析过程与语言环境无关
  • 格式化即将日期转成字符串,解析即将字符串转成日期
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class SimpleDateFormatTest {
    public static void main(String[] args) {
        // 使用默认空参构造器
        SimpleDateFormat sdf1 = new SimpleDateFormat();
        // 格式化
        String str1 = sdf1.format(new Date());
        System.out.println(str1);
        // 解析字符串
        String str2 = "2020/02/01 下午04:20";
        try {
            //要求字符串必须是符合 SimpleDateFormat 识别的格式(通过构造器参数体现)
            Date date = sdf1.parse(str2);
            System.out.println(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        // 在构造器指定进行格式化和解析的日期的格式
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        // 格式化
        String str3 = sdf2.format(new Date());
        System.out.println(str3);
        // 解析
        String str4 = "2020-02-01 15:20:30";
        try {
            Date date = sdf2.parse(str4);
            System.out.println(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}

java.time 包下的 LocalDateTime 等

java.time 包提供了 LocalDate 本地日期、LocalTime 本地时间、LocalDateTime 本地日期时间、ZonedDateTime 时区、Duration 持续时间

import java.time.LocalDate;
import java.time.LocalTime;
import java.time.LocalDateTime;

public class LocalDateTimeTest {
    public static void main(String[] args) {
        // 对象实例化
        // 获取表示当前时间的对象
        LocalDateTime localDateTime1 = LocalDateTime.now();
        // 获取表示某个时间的对象
        LocalDateTime localDateTime2 = LocalDateTime.of(2020,2,1,16,35,10,340);
        // 日期
        LocalDate localDate = LocalDate.now();
        // 时间
        LocalTime localTime = LocalTime.now();

        System.out.println(localDateTime1);
        System.out.println(localDateTime2);
        System.out.println(localDate);
        System.out.println(localTime);

        // 获取:get 方法
        System.out.println(localDate.getDayOfMonth());
        System.out.println(localDate.getDayOfYear());
        System.out.println(localDate.getMonth());
        System.out.println(localDate.getMonthValue());
        System.out.println(localDateTime1.getMinute());

        // 设置:with 方法
        // 修改日期,并返回新的 LocalDateTime 对象
        LocalDateTime localDateTime3 = localDateTime1.withDayOfMonth(5);
        LocalDateTime localDateTime4 = localDateTime1.withMonth(1);
        System.out.println(localDateTime3);
        System.out.println(localDateTime4);
        // 原来的对象并未改变
        System.out.println(localDateTime1);

        // 增加时间 plus 方法,减少时间 minus 方法
        System.out.println(localDateTime1.plusMinutes(20));
        System.out.println(localDateTime1.minusHours(2));
    }
}

DateTimeFormatter

  • 用于格式化或解析日期、时间,类似于 SimpleDateFormat
  • 使用 LocalDateTime 时,如果要进行格式化显示,就要使用 DateTimeFormatter
  • 和 SimpleDateFormat 不同的是,DateTimeFormatter 不但是不变对象,它还是线程安全的
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class DateTimeFormatterTest {
    public static void main(String[] args) {
        // 创建一个 DateTimeFormatter 对象,并指定格式化、解析的日期时间格式
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm");
        // 将日期时间格式化为字符串
        String str = dtf.format(LocalDateTime.now());
        System.out.println(str);
        // 将字符串按照 DateTimeFormatter 对象指定的格式解析为时间
        System.out.println(dtf.parse(str));
        // 不按指定格式,会报java.time.format.DateTimeParseException异常
        System.out.println(dtf.parse("2020/3/15 18:20"));
    }
}

Java 比较器

如果要实现对象之间的比较,需要实现 Comparable 或 Comparator 接口

  • 自然排序 java.lang.Comparable
  • 定制排序 java.util.Comparator
  • Comparable 接口的方式一旦确定,保证 Comparable 接口实现类的对象在任何位置都可以比较大小。
  • Comparator 接口常用于临时性的比较

Comparable 接口

  • 实现了 Comparable 接口并且重写 comparaTo(Object obj) 方法的类的对象可以进行比较,例如 String、包装类等
  • 重写 comparaTo(Object obj) 方法的规则
    • 如果当前对象 this 大于形参对象 obj,返回正整数
    • 如果当前对象 this 小于形参对象 obj,返回负整数
    • 如果当前对象 this 等于形参对象 obj,返回零
  • 对于自定义的类,如果需要排序,例如存储自定义类对象的数组或集合要调用 Arrays.sort() 或 Collections.sort(),则必须实现 Comparable 接口,并在 comparaTo() 方法中指明如何排序
import java.util.Arrays;

public class ComparableTest {
    public static void main(String[] args) {
        Goods[] goods = new Goods[5];
        goods[0] = new Goods(40,"huawei");
        goods[1] = new Goods(35,"xiaomi");
        goods[2] = new Goods(43,"oppo");
        goods[3] = new Goods(20,"vivo");
        goods[4] = new Goods(43,"apple");
        System.out.println(Arrays.toString(goods));
        Arrays.sort(goods);
        System.out.println(Arrays.toString(goods));
    }
}

class Goods implements Comparable{
    double price;
    String name;

    Goods(){}

    Goods(double price,String name) {
       this.price = price;
       this.name = name;
    }

    @Override
    public String toString() {
        return "Goods{" +
                "price=" + price +
                ", name='" + name + '\'' +
                '}';
    }

    @Override
    public int compareTo(Object o) {
        if(o instanceof Goods) {
            Goods anotherGoods = (Goods)o;
            if(this.price > anotherGoods.price) {
                return 1;
            }else if(this.price < anotherGoods.price) {
                return -1;
            }else {
                // return 0;
                // 二级排序
                return this.name.compareTo(anotherGoods.name);
            }
            // 比较数值也可以使用包装类的compara方法
            // return Double.compare(this.price,anotherGoods.price);
        }
        throw new RuntimeException("传入类型不正确");
    }
}

Comparator 接口

  • 当元素的类型没实现 java.lang.Comparable 接口而又不方便修改代码,或者实现了 java.lang.Comparable 接口的排序规则不适合当前的操作,那么可以考虑使用 java.util.Comparator 的对象来排序
  • 重写 compare(Object o1,Object o2) 方法,比较o1和o2的大小:
    • 如果方法返回正整数,则表示o1大于o2
    • 如果返回0,表示相等
    • 返回负整数,表示o1小于o2
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class ComparatorTest {
    public static void main(String[] args) {
        ArrayList<Phone> phone = new ArrayList<>();
        phone.add(new Phone(100,"huawei"));
        phone.add(new Phone(99,"xiaomi"));
        phone.add(new Phone(90,"oppo"));
        phone.add(new Phone(90,"apple"));

        System.out.println(phone);
        // 匿名内部类的方式使用 Comparator 接口
        Collections.sort(phone, new Comparator<Phone>() {
            @Override
            public int compare(Phone o1, Phone o2) {
                if(o1.price!=o2.price) {
                    return Double.compare(o1.price,o2.price);
                }else {
                    return o1.name.compareTo(o2.name);
                }
            }
        });
        System.out.println(phone);
    }
}

class Phone {
    double price;
    String name;

    public Phone() {
    }

    public Phone(double price, String name) {
        this.price = price;
        this.name = name;
    }

    @Override
    public String toString() {
        return "Phone{" +
                "price=" + price +
                ", name='" + name + '\'' +
                '}';
    }
}

System 类

  • java.lang.System 类代表系统,系统级的很多属性和控制方法都放置在该类的内部
    该类的构造器是 private 的,无法实例化,其成员变量和成员方法都是 static 的,方便进行调用。
  • 常用方法
// 获取时间戳
long currentTimeMillis()
// 推出程序
void exit(int status)
// 通知 JVM 进行垃圾回收
void gc()
// 将数组中指定的数据拷贝到另一个数组中
public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
/*
  src - 源数组。 
  srcPos - 源数组中的起始位置,(起始索引) 
  dest - 目标数组。
  destPos - 目的地数据中的起始位置
  length - 要复制的数组元素的数量 
*/

Math 类

java.lang.Math 类提供了一系列静态方法用于数值计算,如指数、对数、平方根、三角函数等

// 求绝对值
Math.abs(-7.8); // 7.8

// 求较大、较小值
Math.max(100, 99); // 100
Math.min(1.2, 2.3); // 1.2

// 乘方
Math.pow(2, 10); // 2的10次方=1024

// 开方
Math.sqrt(2); // 1.414...

// e 的多少次方
Math.exp(2); // 7.389...

// 以 e 为底的对数
Math.log(4); // 1.386...

// 计算以10为底的对数
Math.log10(100); // 2

// 三角函数
Math.sin(3.14); // 0.00159...
Math.cos(3.14); // -0.9999...
Math.tan(3.14); // -0.0015...
Math.asin(1.0); // 1.57079...
Math.acos(1.0); // 0.0

// 数学常量
double pi = Math.PI; // 3.14159...
double e = Math.E; // 2.7182818...

// 生成一个随机数x,x的范围是0 <= x < 1:
Math.random();

BigInteger 和 BigDecimal

BigInteger

  • 由 CPU 原生提供的整型最大范围是 64 位 long 型整数,使用 long 型整数可以直接通过CPU指令进行计算,速度非常快
  • 如果需要的整数大小超过了 long 的范围,可以使用 BigInteger。java.math.BigInteger 可以表示不可变的任意精度的整数,其内部用一个 int[] 数组来模拟一个非常大的整数
  • 对 BigInteger 对象进行运算必须调用对应的实例方法
// 返回两个大整数的和
BigInteger add(BigInteger val) 

// 返回两个大整数的差
BigInteger subtract(BigInteger val)

// 返回两个大整数的积
BigInteger multiply(BigInteger val)

// 返回两个大整数的商
BigInteger divide(BigInteger val)

// 用当前大整数对val求模
BigInteger mod(BigInteger val) 

// 返回两个大整数的最大者
BigInteger max(BigInteger val)

// 返回两个大整数的最小者
BigInteger min(BigInteger val) 

// 返回绝对值
BigInteger abs()

// 返回相反数
BigInteger negate()

// 返回大整数的double类型的值
double doubleValue()

// 返回大整数的float类型的值
float floatValue()

// 返回大整数的整型值
int intValue()

// 返回大整数的long型值
long longValue() 
  • 可以调用相应的方法将 BigInteger 转换成基本数据类型
    • 如果 BigInteger 表示的范围超过了基本类型的范围,转换时将丢失高位信息,即结果不一定是准确的
    • 如果需要准确地转换成基本类型,可以使用 intValueExact()、longValueExact() 等方法,在转换时如果超出范围,将抛出 ArithmeticException 异常
BigInteger i = new BigInteger("123456789000");
System.out.println(i.longValue()); // 123456789000
System.out.println(i.multiply(i).longValueExact()); // java.lang.ArithmeticException: BigInteger out of long range

BigDecimal

  • 和 BigInteger 类似,BigDecimal 可以表示一个任意大小且精度完全准确的浮点数
// 返回 BigDecimal 的小数位数,如果返回负数,表示此 BigDecimal 为正数,该负数的绝对值为 BigDeceimal 结尾的 0 的个数
int scale()

// 格式化为一个相等的,但去掉了末尾0的BigDecimal
BigDecimal stripTrailingZeros()
  • 总是使用 compareTo() 比较两个 BigDecimal 的值是否相同,不要使用 equals()

Copyright: 采用 知识共享署名4.0 国际许可协议进行许可

Links: https://yzt.cool/archives/2020-03-15-javausefulclasses