Java常用的一些类

Java常用的一些类

1.LocalDate类

我们先看一个代码:

import java.time.LocalDate;


public class DateTest {

  public static void main(String[] args) {
    // 得到当前的完整时间
    LocalDate now = LocalDate.now();
    // 打印出时间
    System.out.println(now.toString());
  }
}

我们在使用之前就需要导入java.time.LocalDate 的包才能使用,我们调用now()方法就是相当于返回现在计算机系统时间

得到2020-08-03

日期时间和字符串转化:

我们发现格式有些时候不是我们很想要的,我们该怎么转换呢?

我们又要导入一个类:DateTimeFormatter类,完整包路径是java.time.format.DateTimeFormatter,所以我们还需要使用import来进行导入,看代码:

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

public class DateTest5 {

  public static void main(String[] args) {

    LocalDate time = LocalDate.now();
    // 打印默认的时间数据
    System.out.println(time.toString());

    // 创建一个格式化方式
    DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy年MM月dd");
    // 执行时间的格式化处理,得到期望格式的时间字符串
    String timeStr = df.format(time);
    // 打印时间
    System.out.println(timeStr);

  }
}

结果如下:

2020-08-03
2020年08月03日

我们现在只想要里面某一些具体的值怎么办?

import java.time.LocalDate;

public class DateTest7 {

  public static void main(String[] args) {

    LocalDate time = LocalDate.now();

    // 得到当前时间所在年
    int year = time.getYear();
    System.out.println("当前年份 " + year);

    // 得到当前时间所在月
    int month = time.getMonth().getValue();
    System.out.println("当前月份 " + month);

    // 得到当前时间在这个月中的天数
    int day = time.getDayOfMonth();
    System.out.println("当前日 " + day);

    // 得到当前时间所在星期数
    int dayOfWeek = time.getDayOfWeek().getValue();
    System.out.println("当前星期 " + dayOfWeek);

  }
}

我们有这些方法:

我们还看到了getValue()方法,一些没有,为什么呢,我们看看相关源代码:

/**
     * 获取年
     */
    public int getYear() {
        return year;
    }

    /**
     * 获取月份
     */
    public int getMonthValue() {
        return month;
    }

    /**
     * 获取英文的那种月份
     */
    public Month getMonth() {
        return Month.of(month);
    }

    /**
     * 获取日
     */
    public int getDayOfMonth() {
        return day;
    }

    /**
     * 获取一年中的第几天
     */
    public int getDayOfYear() {
        return getMonth().firstDayOfYear(isLeapYear()) + day - 1;
    }
/**
     * 获取1周中的第几天
     */
    public DayOfWeek getDayOfWeek() {
        int dow0 = (int)Math.floorMod(toEpochDay() + 3, 7);
        return DayOfWeek.of(dow0 + 1);
    }

我们可以看到,getyear和getday方法,源码中返回类型是int,所以可以直接获取值,而getMonth和getDayOfWeek的返回类型是Month和DayOfWeek,所以返回的不是int,需要用getValue方法去获取值。

因为 getMonth()getDayOfWeek() 的返回值是对象,不是具体的整数值。

返回对象的原因是一年只有 12 个月、每周 7 天都是可以枚举的,使用对象可以比较好的防止出现 13 月。

把时间转换成字符串我们使用了time.toString()的方法,,但是我们有些时候会把字符串转换成LocalDate方法。

import java.time.LocalDate;

public class DateTest8 {

  public static void main(String[] args) {
    // 定义一个时间字符串,日期是2019年1月1日
    String date = "2019-01-01";

    // 把字符串转化位 LocalDate 对象,并得到字符串匹配的日期
    LocalDate date2 = LocalDate.parse(date);
    // 打印出日期
    System.out.println(date2.toString());
  }
}

如上代码,LocalDate.parse(date) 这个 parse 方法可以把日期字符串转化为日期类型,注意这个字符串格式是 年-月-日 时:分:秒(英文格式是:yyyy-MM-dd HH:mm:ss)年是 4 位数字(yyyy),月是 2 位数字(MM),日是 2 位数字(DD),这个格式不能错哦。

但是,如果日期格式不是yyyy-MM-dd,就要借助DateTimeFormatter方法。

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

public class DateTest81 {

  public static void main(String[] args) {
    // 定义一个时间字符串,日期是2019年1月1日
    String date = "2019/01/01";

    DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy/MM/dd");

    // 把字符串转化位 LocalDate 对象,并得到字符串匹配的日期
    LocalDate date2 = LocalDate.parse(date,df);
    // 打印出日期
    System.out.println(date2.toString());
  }
}

计算时间的方法:

我们来看一段代码:

import java.time.LocalDate;

public class DateTest9 {

  public static void main(String[] args) {

    LocalDate leaveTime = getLeaveTime("2019-05-01", 4);
    System.out.println(leaveTime.toString());
  }

  /**
   * 根据入住时间和入住天数得到离店时间
   *
   * @param checkInTime
   * @param days
   * @return
   */
  public static LocalDate getLeaveTime(String checkInTime, int days) {
    // 把字符串转化为 LocalDate 类型
    LocalDate time = LocalDate.parse(checkInTime);
    // 使用 plusDays 添加天数,得到新的时间
    LocalDate leaveTime = time.plusDays(days);
    return leaveTime;
  }

}

我们需要加上几天时间,我们需要用plusDays方法进行相加

结果是2019-05-05

另外,还有加几个月几年,或者减几个月,几年的

import java.time.LocalDate;

public class DateTest10 {

  public static void main(String[] args) {

    LocalDate now = LocalDate.now();
    System.out.println("当前:" + now.toString());

    System.out.println("加法运算");
    System.out.println("加1天:" + now.plusDays(1));
    System.out.println("加1周:" + now.plusWeeks(1));
    System.out.println("加1月:" + now.plusMonths(1));
    System.out.println("加1年:" + now.plusYears(1));

    System.out.println("减法运算");
    System.out.println("减1天:" + now.minusDays(1));
    System.out.println("减1周:" + now.minusWeeks(1));
    System.out.println("减1月:" + now.minusMonths(1));
    System.out.println("减1年:" + now.minusYears(1));

  }

}

和相关英文单词差不多,

当前:2020-08-04
加法运算
加1天:2020-08-05
加1周:2020-08-11
加1月:2020-09-04
加1年:2021-08-04
减法运算
减1天:2020-08-03
减1周:2020-07-28
减1月:2020-07-04
减1年:2019-08-04

两个日期的判断:

import java.time.LocalDate;

public class DateTest11 {

  public static void main(String[] args) {

    LocalDate now = LocalDate.now();

    // 可以对两个 LocalDate 进行比较,
    // 可以判断一个日期是否在另一个日期之前或之后,
    // 或者判断两个日期是否是同年同月同日。

    boolean isBefore = now.minusDays(1).isBefore(LocalDate.now());

    System.out.println("是否在当天之前:" + isBefore);

    boolean isAfter = now.plusDays(1).isAfter(LocalDate.now());
    System.out.println("是否在当天之后:" + isAfter);


    // 判断是否是当天
    boolean sameDate = now.isEqual(LocalDate.now());
    System.out.println("是否在当天:" + sameDate);
  }

}

isBefore的含义是在前几天,isAfter含义是后几天,isEqual是和哪天相等吗?

结果是:

是否在当天之前:true
是否在当天之后:true
是否在当天:true

2.Date类

在计算机中,应该如何表示日期和时间呢?

我们经常看到的日期和时间表示方式如下:

  • 2019-11-20 0:15:00 GMT+00:00
  • 2019年11月20日8:15:00
  • 11/19/2019 19:15:00 America/New_York

如果直接以字符串的形式存储,那么不同的格式,不同的语言会让表示方式非常繁琐。

它们实际上是数据的展示格式,分别按英国时区、中国时区、纽约时区对同一个时刻进行展示。而这个“同一个时刻”在计算机中存储的本质上只是一个整数,我们称它为Epoch Time

Epoch Time是计算从1970年1月1日零点(格林威治时区/GMT+00:00)到现在所经历的秒数,例如:

1574208900表示从从1970年1月1日零点GMT时区到该时刻一共经历了1574208900秒,换算成伦敦、北京和纽约时间分别是:

1574208900 = 北京时间2019-11-20 8:15:00
           = 伦敦时间2019-11-20 0:15:00
           = 纽约时间2019-11-19 19:15:00

Epoch Time又称为时间戳,在不同的编程语言中,会有几种存储方式:

  • 以秒为单位的整数:1574208900,缺点是精度只能到秒;
  • 以毫秒为单位的整数:1574208900123,最后3位表示毫秒数;
  • 以秒为单位的浮点数:1574208900.123,小数点后面表示零点几秒。

它们之间转换非常简单。而在Java程序中,时间戳通常是用long表示的毫秒数,即:

long t = 1574208900123L;

java.util.Date是用于表示一个日期和时间的对象,注意与java.sql.Date区分,后者用在数据库中。

我们来看一下date的基本用法:

import java.util.*;
public class Main {
    public static void main(String[] args) {
        // 获取当前时间:
        Date date = new Date();
        System.out.println(date.getYear() + 1900); // 必须加上1900
        System.out.println(date.getMonth() + 1); // 0~11,必须加上1
        System.out.println(date.getDate()); // 1~31,不能加1
        // 转换为String:
        System.out.println(date.toString());
        // 转换为GMT时区:
        System.out.println(date.toGMTString());
        // 转换为本地时区:
        System.out.println(date.toLocaleString());
    }
}

getYear如果不加1900,就会变成现在时间减去1900得到的数字

getMonth()返回的月份是0`11`分别表示112月,所以要加1,而getDate()返回的日期范围是1~31,又不能加1。

但是我们发现时间晚着8个小时,因为它返回了英国格林尼治时间。就是世界标准时间。

打印本地时区表示的日期和时间时,不同的计算机可能会有不同的结果。如果我们想要针对用户的偏好精确地控制日期和时间的格式,就可以使用SimpleDateFormat对一个Date进行转换。它用预定义的字符串表示格式化:

  • yyyy:年
  • MM:月
  • dd: 日
  • HH: 小时
  • mm: 分钟
  • ss: 秒

自定义格式输出:

import java.text.*;
import java.util.*;
public class Main {
    public static void main(String[] args) {
        // 获取当前时间:
        Date date = new Date();
        var sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println(sdf.format(date));
    }
}

自定义输出我们使用了SimpleDateFormat函数。

我们查看它的源码:由于SimpleDateFormat继承了一个类:DateFormat类,这个是一个抽象类,

上述代码在不同的语言环境会打印出类似Sun Sep 15, 2019这样的日期。我们可以查看相关文档:https://docs.oracle.com/en/java/javase/12/docs/api/java.base/java/text/SimpleDateFormat.html

这个文档是全英文的,不过我们可以通过解释来大致介绍:

但是date是有缺陷的,一般来说,字母越长,输出越长。以M为例,假设当前月份是9月:

  • M:输出9
  • MM:输出09
  • MMM:输出Sep
  • MMMM:输出September

Date对象有几个严重的问题:它不能转换时区,除了toGMTString()可以按GMT+0:00输出外,Date总是以当前计算机系统的默认时区为基础进行输出。此外,我们也很难对日期和时间进行加减,计算两个日期相差多少天,计算某个月第一个星期一的日期等。

所以我们引入了Calendar类

3.Calendar类

Calendar可以用于获取并设置年、月、日、时、分、秒,它和Date比,主要多了一个可以做简单的日期和时间运算的功能。

我们来看Calendar的基本用法:

import java.util.*;

public class Main {
    public static void main(String[] args) {
        // 获取当前时间:
        Calendar c = Calendar.getInstance();
        int y = c.get(Calendar.YEAR);
        int m = 1 + c.get(Calendar.MONTH);
        int d = c.get(Calendar.DAY_OF_MONTH);
        int w = c.get(Calendar.DAY_OF_WEEK);
        int hh = c.get(Calendar.HOUR_OF_DAY);
        int mm = c.get(Calendar.MINUTE);
        int ss = c.get(Calendar.SECOND);
        int ms = c.get(Calendar.MILLISECOND);
        System.out.println(y + "-" + m + "-" + d + " " + w + " " + hh + ":" + mm + ":" + ss + "." + ms);
    }
}

我们为什么不直接new一个Calendar呢?我们先看看源代码:

发现是一个抽象类,可以获得现在时间。

注意到Calendar获取年月日这些信息变成了get(int field),返回的年份不必转换,返回的月份仍然要加1,返回的星期要特别注意,1~7分别表示周日,周一,……,周六。

Calendar只有一种方式获取,即Calendar.getInstance(),而且一获取到就是当前时间。如果我们想给它设置成特定的一个日期和时间,就必须先清除所有字段:

import java.text.*;
import java.util.*;

public class Main {
    public static void main(String[] args) {
        // 当前时间:
        Calendar c = Calendar.getInstance();
        // 清除所有:
        c.clear();
        // 设置2019年:
        c.set(Calendar.YEAR, 2019);
        // 设置9月:注意8表示9月:
        c.set(Calendar.MONTH, 8);
        // 设置2日:
        c.set(Calendar.DATE, 2);
        // 设置时间:
        c.set(Calendar.HOUR_OF_DAY, 21);
        c.set(Calendar.MINUTE, 22);
        c.set(Calendar.SECOND, 23);
        System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(c.getTime()));
        // 2019-09-02 21:22:23
    }
}

利用Calendar.getTime()可以将一个Calendar对象转换成Date对象,然后就可以用SimpleDateFormat进行格式化了。

TimeZone

CalendarDate相比,它提供了时区转换的功能。时区用TimeZone对象表示:

import java.util.*;
public class Main {
    public static void main(String[] args) {
        TimeZone tzDefault = TimeZone.getDefault(); // 当前时区
        TimeZone tzGMT9 = TimeZone.getTimeZone("GMT+09:00"); // GMT+9:00时区
        TimeZone tzNY = TimeZone.getTimeZone("America/New_York"); // 纽约时区
        System.out.println(tzDefault.getID()); // Asia/Shanghai
        System.out.println(tzGMT9.getID()); // GMT+09:00
        System.out.println(tzNY.getID()); // America/New_York
    }
}

时区的唯一标识是以字符串表示的ID,我们获取指定TimeZone对象也是以这个ID为参数获取,GMT+09:00Asia/Shanghai都是有效的时区ID。要列出系统支持的所有ID,请使用TimeZone.getAvailableIDs()

我们想要转换成北京时间,就这么个:

import java.text.*;
import java.util.*;

public class Main {
    public static void main(String[] args) {
        // 当前时间:
        Calendar c = Calendar.getInstance();
        // 清除所有:
        c.clear();
        // 设置为北京时区:
        c.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        // 设置年月日时分秒:
        c.set(2019, 10 /* 11月 */, 20, 8, 15, 0);
        // 显示时间:
        var sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        sdf.setTimeZone(TimeZone.getTimeZone("America/New_York"));
        System.out.println(sdf.format(c.getTime()));
        // 2019-11-19 19:15:00
    }
}

计算机表示的时间是以整数表示的时间戳存储的,即Epoch Time,Java使用long型来表示以毫秒为单位的时间戳,通过System.currentTimeMillis()获取当前时间戳。

4.BigInteger类

在Java中,由CPU原生提供的整型最大范围是64位long型整数。使用long型整数可以直接通过CPU指令进行计算,速度非常快。

如果我们使用的整数范围超过了long型怎么办?这个时候,就只能用软件来模拟一个大整数。java.math.BigInteger就是用来表示任意大小的整数。BigInteger内部用一个int[]数组来模拟一个非常大的整数:

BigInteger bi = new BigInteger("1234567890");
System.out.println(bi.pow(5)); // 2867971860299718107233761438093672048294900000

BigInteger做运算的时候,只能使用实例方法,例如,加法运算:

BigInteger i1 = new BigInteger("1234567890");
BigInteger i2 = new BigInteger("12345678901234567890");
BigInteger sum = i1.add(i2); // 12345678902469135780

long型整数运算比,BigInteger不会有范围限制,但缺点是速度比较慢。

也可以把BigInteger转换成long型:

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

加法:add,减法:subtract,乘法:multiply,除法:divide

5.BigDecimal类

BigInteger类似,BigDecimal可以表示一个任意大小且精度完全准确的浮点数。

BigDecimal bd = new BigDecimal("123.4567");
System.out.println(bd.multiply(bd)); // 15241.55677489

这个用法和BigInterger方法一模一样。不一样的是:

BigDecimalscale()表示小数位数,例如:

BigDecimal d1 = new BigDecimal("123.45");
BigDecimal d2 = new BigDecimal("123.4500");
BigDecimal d3 = new BigDecimal("1234500");
System.out.println(d1.scale()); // 2,两位小数
System.out.println(d2.scale()); // 4
System.out.println(d3.scale()); // 0

具体可以看看文档:https://www.liaoxuefeng.com/wiki/1252599548343744/1279768011997217

6.Scanner类

我们以前经常干打印输出的活,现在我们来看看怎么从控制台里面输入:

我们引入了Scanner类来进行输入

Scanner类不仅可以输入,还可以解析字符串对象。

Scanner scanner = new Scanner(str)

我们知道Scanner不能直接导入,要导入java.util.Scanner包才可以。

解析字符串以外输入语法如下:

Scanner scanner = new Scanner(System.in)

System.in表示输入的语法。

要怎么来输入或者解析呢?

我们用next相关来解析:基本数据类型:scanner.next+首字母大写的基本数据类型

字符串:scanner.next()

我们有疑问,为什么system可以进行输入输出呢?

我们来看看System类

7.System类

我们打开源代码,发现是一个最终类,说明system类不能被继承。

in方法是一个输入流对象的实例化,out是一个输出流对象。

具体方法我们看看输入流与输出流再说。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值