1、System 类
这个类的构造器是私有的,所有不能创建这个类的对象。要想使用,只能是通过调用其静态方法。
1.1、currentTimeMillis() 静态方法
获取当前时间与1970年1月1日0时0分0秒的时间差,单位为毫秒,返回值是一个long型数。
这种毫秒数通常叫做时间戳。以下统一叫做时间戳。
long l = System.currentTimeMillis();
1.2 exit 方法
exit(int status) 退出程序, 参数status为 0 表示正常退出。非0即异常退出
在图形化界面中,可以使用该方法进行退出程序。
1.3 gc 方法
void gc() 方法是 请求系统进行垃圾回收,至于系统是否立即回收,取决于系统中垃圾回收算法的实现以及系统执行时的情况。
1.4 getProperty 方法
String getProperty(String key) 方法 获取系统中属性名为key的属性对应的值。
系统有上图这些常用的属性。
2、Date 类
这里讲的Date类在 java.util包下。
注意 java.sql下也有一个Date类。而且是util包下的子类。
2.1 使用【 java.util.Date】
1、构造器使用
- 无参构造器:创建一个对应当前时间的对象
Date date = new Date();
System.out.println(date);
// 输出 这样输出是因为Date类中重写的toString方法。返回的是当前的 年月日时分秒
Tue Aug 10 19:19:44 CST 2021
- 有参构造器1: 创建一个指定时间的对象。已经过时,不建议使用。
Date date1 = new Date(2010, 1, 31);
- 有参构造器2:根据时间戳创建一个时间对象。
Date date1 = new Date(1628594619869L);
System.out.println(date1);
// 输出
Tue Aug 10 19:23:39 CST 2021
2、方法
getTime方法: 也是返回当前时间戳
Date date = new Date();
System.out.println(date.getTime());
// 输出
// 1628594619869
2.2、数据库中的Date类
【 java.sql.Date】
Date date = new Date();
// 如果已经导了util的Date,创建同名的sql下的Date对象就要写全类名
java.sql.Date date1 = new java.sql.Date(1628594619869L);
System.out.println(date1);
// 输出: 2021-08-10
只输出 2021-08-10 说明 sql包下的Date也是重写了toString方法的。
如果互转?
1、sql(子)下转 util (父)的Date
直接赋值即可,利用多态。
2、util (父)转 sql(子) 对象
Date date = new Date();
// 利用构造器转换,先获取时间戳。
java.sql.Date date1 = new java.sql.Date(date.getTime());
System.out.println(date1);
3、SimpleDateFormat 类
SimpleDateFormat 这是一个对日期进行格式化的类。
1、格式化:日期 转 字符串
@Test
public void DateTest(){
// 实例化日期格式化类
SimpleDateFormat dateFormat = new SimpleDateFormat();
// 生成一个当前时间对象
Date date = new Date();
// 格式化
String format = dateFormat.format(date);
System.out.println(format);
}
// 输出:
21-8-11 下午6:56
2、解析:字符串 转 日期
@Test
public void DateTest() throws ParseException {
// 实例化日期格式化类
SimpleDateFormat dateFormat = new SimpleDateFormat();
// 默认解析
String str = "21-8-11 下午7:00";
Date parse = dateFormat.parse(str);
System.out.println(parse);
}
// 输出
Wed Aug 11 19:00:00 CST 2021
@Test
public void DateTest() throws ParseException {
// 实例化日期格式化类,指定格式化形式
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
String str = "2001-07-04T12:08:56.235-0700";
Date parse = dateFormat.parse(str);
System.out.println(parse);
}
上图为支持的字符串格式。否则会抛异常。
4、Calendar 类
日历类
这是一个抽象类。不能直接new对象
1、实例化
// 方式1:创建其子类 GregorianCalendar
GregorianCalendar calendar = new GregorianCalendar();
// 方式2:调用静态方法 getInstance() 实际还是子类GregorianCalendar的对象
Calendar instance = Calendar.getInstance();
2、常用方法
- get 方法
// 获取今天是这个月的第几天。今天11号
int i = calendar.get(Calendar.DAY_OF_MONTH);
System.out.println(i); // 11
类似的,可以获取这一周的第几天,今天的第几天。以及这个月的第几周。
- set 方法 修改当前对象
Calendar calendar = Calendar.getInstance();
System.out.println(calendar.get(Calendar.DAY_OF_MONTH)); // 11
calendar.set(Calendar.DAY_OF_MONTH, 20);
System.out.println(calendar.get(Calendar.DAY_OF_MONTH)); // 20
- add 方法 也是修改当前对象,是添加。 如果要减去几天 就是 添加一个负数
Calendar calendar = Calendar.getInstance();
System.out.println(calendar.get(Calendar.DAY_OF_MONTH)); // 11
calendar.add(Calendar.DAY_OF_MONTH, 3);
System.out.println(calendar.get(Calendar.DAY_OF_MONTH)); // 14
- getTime 方法 获取Date对象 相当于 日历类转 Date类
Calendar calendar = Calendar.getInstance();
Date time = calendar.getTime();
System.out.println(time); // Wed Aug 11 19:36:28 CST 2021
- setTime 方法 getTime的逆过程
Calendar calendar = Calendar.getInstance();
Date time = new Date();
calendar.setTime(time);
System.out.println(calendar.get(Calendar.DAY_OF_MONTH)); // 11
注意: 月份是从0开始。 1月是0 、12月是11
获取星期时, 周日是1,周六是7
5、JDK 8 新时间Api
JDK8之前的Date类的缺点:
- 可变性:像日期和时间应该是不可变的,而Date和Calendar都是可变的。
- 偏移性:Date中的年份是从1900年开始,月份从0开始
Date time = new Date(2021, 7, 12);
System.out.println(time);
// Fri Aug 12 00:00:00 CST 3921
我们期望的是2021年7月12日,而事实上确实3921年8月12日。因为Date是从1900年开始的,月份从0开始. 需要减去偏移量才能得到想要的。如下面的代码:
Date time1 = new Date(2021 - 1900, 7 - 1, 12);
System.out.println(time1);
// Mon Jul 12 00:00:00 CST 2021
- 格式化:格式化只对Date有效,Calendar 不能格式化
- 安全性:不是线程安全的
5.1 新Api java.time、java.format包
- LocalDate:本地日期
- LocalTime:本地时间
- LocalDateTime:本地日期时间
1、now() 方法:获取当前时间 【类方法】
// 本地日期
LocalDate date = LocalDate.now();
// 本地时间
LocalTime time = LocalTime.now();
// 本地日期时间
LocalDateTime dateTime = LocalDateTime.now();
System.out.println(date);
System.out.println(time);
System.out.println(dateTime);
// 输出
2021-08-12
07:46:06.166
2021-08-12T07:46:06.166
实例化的第一种方法。获取当前的日期、时间等。
2、of() 方法:指定日期时间的方法。没有偏移量【类方法】
LocalDate date = LocalDate.of(2020, 5, 20);
LocalTime time = LocalTime.of(5,20,20);
LocalDateTime dateTime = LocalDateTime.of(2020, 5, 20, 5, 20, 20);
System.out.println(date);
System.out.println(time);
System.out.println(dateTime);
// 输出
2020-05-20
05:20:20
2020-05-20T05:20:20
以上2个方法为类方法,通过类名调用。
3、getxxx方法 : 获取时间 【成员方法】
这3个类都有类似的方法,为了简单,只以 LocalDateTime 为例。
// 类方法now 获取对象
LocalDateTime dateTime = LocalDateTime.now();
// 获取本月第几天
int dayOfMonth = dateTime.getDayOfMonth();
// 获取 星期几
DayOfWeek dayOfWeek = dateTime.getDayOfWeek();
// 获取 今天是今年的第几天
int dayOfYear = dateTime.getDayOfYear();
// 获取 小时
int hour = dateTime.getHour();
// 获取 月份
Month month = dateTime.getMonth();
// 获取 分钟
int minute = dateTime.getMinute();
// 获取 年份
int year = dateTime.getYear();
// 获取 秒
int second = dateTime.getSecond();
// 获取 纳秒
int nano = dateTime.getNano();
System.out.println(dayOfMonth); // 12
System.out.println(dayOfWeek); // THURSDAY
System.out.println(dayOfYear); // 224
System.out.println(hour); // 7
System.out.println(month); // AUGUST
System.out.println(minute); // 59
System.out.println(year); // 2021
System.out.println(second); // 19
System.out.println(nano); // 429000000
4、with 方法:修改、设置时间。相对于对象的时间,返回新的对象 【成员方法】
LocalDateTime dateTime = LocalDateTime.now();
System.out.println(dateTime); // 2021-08-12T08:08:11.547
LocalDateTime dateTime1 = dateTime.withDayOfMonth(20);
System.out.println(dateTime1); // 2021-08-20T08:08:11.547
使用 dateTime 调用 withDayOfMonth(20) 方法 得到了相对 dateTime 对象的月份的第20天的 一个LocalDateTime对象 dateTime1,不会修改原来的dateTime对象。即不可变了。
LocalDateTime dateTime = LocalDateTime.now();
System.out.println(dateTime); // 2021-08-12T08:40:23.263
// 修改月份为5月,得到新的对象。原对象不变。
LocalDateTime dateTime1 = dateTime.withMonth(5);
System.out.println(dateTime1); // 2021-05-12T08:40:23.263
5、plus 方法:加,也是相对当前对象进行运算,得到新对象。【成员方法】
可以加小时,天、分钟、月、周、年等等。如果是加一个负数,就是减。
LocalDateTime dateTime = LocalDateTime.now();
System.out.println(dateTime); //2021-08-12T08:46:46.246
// 在dateTime基础上加上5天
LocalDateTime dateTime1 = dateTime.plusDays(5);
// 在dateTime基础上加上-5天,即减去5天
LocalDateTime dateTime2 = dateTime.plusDays(-5);
System.out.println(dateTime1); //2021-08-17T08:46:46.246
System.out.println(dateTime2); //2021-08-07T08:46:46.246
// 运算后原对象不变
System.out.println(dateTime); //2021-08-12T08:46:46.246
5.2 Instant 类 瞬时
在java中,以1970年开始,以毫秒为单位计算。
linux是1970年以秒为单位。
Instant now = Instant.now();
System.out.println(now);
// 输出
2021-08-12T00:53:51.875Z
输出的时间与我们的时间差8个小时。这个是以本初子午线为标准,我们是东八区。需要加上8小时。
- atOffset 方法 设置偏移量 【成员方法】
Instant now = Instant.now();
OffsetDateTime time = now.atOffset(ZoneOffset.ofHours(8));
System.out.println(time);
// 输出
2021-08-12T08:57:03.074+08:00
使用成员方法 atOffset 可以设置偏移量,纠正时间差。
- toEpochMilli 计算 1970-01-01T00:00:00Z 到当前时间的毫秒数 【成员方法】
Instant now = Instant.now();
long l = now.toEpochMilli();
System.out.println(l); // 1628730009228
- ofEpochMilli 通过 毫秒数得到Instance对象 【类方法】
Instant instant = Instant.ofEpochMilli(1628730009228L);
System.out.println(instant);
5.3 格式化类
java.time.format.DateTimeFormatter 类
该类用来格式化或解析日期或者时间
- 预定义的标注格式、国际标准
// 预定义的格式化
DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
LocalDateTime now = LocalDateTime.now();
// 使用成员方法 format 方法将时间格式化为 字符串
String format = formatter.format(now);
System.out.println(format); // 2021-08-13T16:23:34.699
// 字符串解析
TemporalAccessor parse = formatter.parse("2021-08-13T16:22:24.841");
System.out.println(parse); // {},ISO resolved to 2021-08-13T16:22:24.841
预定义的方式看看就好,基本不用。
- 预定义的 本地化相关的格式 ofLocalizedDateTime、ofLocalizedDate
// 使用类方法 ofLocalizedDateTime 获取一个 DateTimeFormatter 对象。
// 参数是一个 FormatStyle 枚举对象
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT);
LocalDateTime now = LocalDateTime.now();
// 调用 format 方法进行格式化
String format = formatter.format(now);
System.out.println(format); // 21-8-13 下午4:29
// 字符串解析
TemporalAccessor parse = formatter.parse("21-8-13 下午4:29");
System.out.println(parse); // {},ISO resolved to 2021-08-13T16:29
这个也是看看就好。
- 自定义的格式 这个才是我们需要的
// 自定义的格式化, yyyy 表示年 MM 月 dd 日 hh 时 mm 分 ss 秒 - 连接符号
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
LocalDateTime now = LocalDateTime.now();
// 格式化
String format = formatter.format(now);
System.out.println(format); // 2021-08-13 04:38:17
// 解析
TemporalAccessor parse = formatter.parse("2021-08-13 04:38:17");
System.out.println(parse);
// {NanoOfSecond=0, MicroOfSecond=0, MinuteOfHour=38, MilliOfSecond=0, SecondOfMinute=17, HourOfAmPm=4},ISO resolved to 2021-08-13
自定义的方式就是使用类方法 ofPattern 得到 DateTimeFormatter 对象。参数就是我们自己定义的 格式。
yyyy 表示年 MM 月 dd 日 hh 时 mm 分 ss 秒 - 连接符号
5.4 转换
6、比较器
正常情况下,java的引用数据类型只能进行比较 地址是否系统 ==
不是比较对象的大小。但是我们可以重新 equals 方法,来比较2个对象是否相等。
这还是比较相等,没有比较大于、小于。
实际开发中,需要对对象进行排序。一般是对对象的某一个属性或者某几个属性进行比较。
java提供了2个比较的接口:Comparable 接口和 Comparator接口
6.1 Comparable
public interface Comparable<T> {
public int compareTo(T o);
}
Comparable 接口只有一个 compareTo方法,返回值为 int型,不抛异常。
String类实现了 Comparable 接口,对compareTo方法进行了实现。所以可以进行比较排序。
public int compareTo(String anotherString) {
int len1 = value.length;
int len2 = anotherString.value.length;
int lim = Math.min(len1, len2);
char v1[] = value;
char v2[] = anotherString.value;
int k = 0;
while (k < lim) {
char c1 = v1[k];
char c2 = v2[k];
if (c1 != c2) {
return c1 - c2;
}
k++;
}
return len1 - len2;
}
上面的代码是String类的重写。可以看一下。
重写 compareTo 的规则:
- 当前对象 this 大于 形参对象,返回正整数 一般是 1
- 当前对象 this 小于 形参对象,返回负整数 一般是 -1
- 当前对象 this 等于 形参对象,返回 0
自定义的类,想要排序,可以实现 Comparable 接口,实现这个 compareTo 方法。
这个用的不多,因为实现这个方法相当于写死了,不灵活。
6.2 Comparator 接口 定制比较
这个接口是因为 我们写的类经常没有实现 Comparable 接口,或者说实现了但是想换一种方式排序,想要更灵活的比较,就出现这个接口。
这个接口的代码较多。可以自己去看源码。
主要 需要实现 compare 方法
int compare(T o1, T o2);
T是泛型。后续介绍。
看下面的例子:
String[] arr = new String[]{"AA","CC","KK","ZZ","JJ"};
Arrays.sort(arr, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return -o1.compareTo(o2);
}
});
在sort方法里面的第二个参数可以传一个 Comparator的实现类对象。这里是使用的匿名实现类,因为只用一次。
这个匿名实现类必须要实现 compare 方法。其实 Comparator 里面还有一个抽象方法既不是 默认方法也不是 静态方法,那就是 equals 方法。按照接口的定义,equals方法是必须要在实现类中实现的。但是这里可以不实现这个方法。原因是 实现类必定继承了Object类。Object类里面已经有这个equals方法的实现了。即如果实现类不重写这个方法,就会直接拿Object类的这个方法。只要可以找到实现的方法体,就没有强制一定要重写。
因此,Comparator 接口只有一个必须要实现的方法 compare。
compare 方法里面写自己的比较逻辑。这里是调用String类自带的compartTo方法,对结果取反,即反向排序。
上面的写法中,指定了泛型为String,如果没有指定,就必须写成下面这种样子:
String[] arr = new String[]{"AA","CC","KK","ZZ","JJ"};
Arrays.sort(arr, new Comparator() {
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof String && o2 instanceof String){
String s1 = (String) o1;
String s2 = (String) o2;
return -s1.compareTo(s2);
}
throw new RuntimeException("输入的数据类型不匹配");
}
});
这个接口实质就是在 compare 接口里面实现 这个compare方法。关键是比较的逻辑编写。
原则还是上面Comparable里面讲的原则。
7、BigInteger、BigDecimal 类
1、BigInteger
可以表示非常大的正数
public class BigInteger extends Number implements Comparable<BigInteger> {}
BigInteger 可以表示 不可变的任意精度的整数。
BigInteger提供所有java的基本整数操作符的对应物。还提供 模运算、GCD运算、质数测试、素数生成、位操作等
2、BigDecimal
一般的float、double类可以用来做科学技术或工程技术,商业计算中,对数字要求精度比较高,需要使用BigDecimal类
public class BigDecimal extends Number implements Comparable<BigDecimal> {}
BigDecimal 支持不可变的、任意精度的有符号十进制定点数。
有很多的构造方法。
里面提供了很多的方法进行运算。