Object类--java核心卷I P174
1:概述:
java.lang.Object
类是Java语言中的根类,即所有类的父类。它中描述的所有方法子类都可以使用。在对象实例化的时候,最终找的父类就是Object.
如果一个类没有特别指定父类, 那么默认则继承自Object类
-
public String toString()
:返回该对象的字符串表示。 -
toString
方法返回该对象的字符串表示,其实该字符串内容就是对象的类型+@+内存地址值。 -
public boolean equals(Object obj)
:指示其他某个对象是否与此对象“相等”。 -
调用成员方法equals并指定参数为另一个对象,则可以判断这两个对象是否是相同的。这里的“相同”有默认和自定义两种方式。
-
默认地址比较
如果没有覆盖重写equals方法,那么Object类中默认进行
==
运算符的对象地址比较,只要不是同一个对象,结果必然为false。对象内容比较
如果希望进行对象的内容比较,即所有或指定的部分成员变量相同就判定两个对象相同,则可以覆盖重写equals方法
package day02;
import java.util.Objects;
public class Persion {
private String name;
private int age;
@Override
public String toString() {
return "Persion{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
// 如果对象地址一样,则认为相同
if (this == o) return true;
// 如果参数为空,或者类信息不一样,则认为不同
if (o == null || getClass() != o.getClass()) return false;
// 转换为当前类型
Persion persion = (Persion) o;
// 要求基本类型相等,并且将引用类型交给java.util.Objects类的equals静态方法取用结果
return age == persion.age &&
Objects.equals(name, persion.name);
}
// 省略构造器与Getter Setter
}
Objects类
在刚才IDEA自动重写equals代码中,使用到了java.util.Objects
类,那么这个类是什么呢?
在JDK7添加了一个Objects工具类,它提供了一些方法来操作对象,它由一些静态的实用方法组成,这些方法是null-save(空指针安全的)或null-tolerant(容忍空指针的),用于计算对象的hashcode、返回对象的字符串表示形式、比较两个对象。
在比较两个对象的时候,Object的equals方法容易抛出空指针异常,而Objects类中的equals方法就优化了这个问题。方法如下:
public static boolean equals(Object a, Object b)
:判断两个对象是否相等。
我们可以查看一下源码,学习一下:
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
//为了防止可能为null的情况,所以前面才使用Objects.equals方法,
//比如如果两个参数都为null,Objects.equals(a,b)将返回true,
//如果其中一个为null,则返回false,
//否则,如果两个参数都不为null,则调用a.equals(b).
2:日期时间类
2.1Date类
java.util.Date
类 表示特定的瞬间,精确到毫秒。
public Date()
:分配Date对象并初始化此对象,以表示分配它的时间(精确到毫秒)。public Date(long date)
:Constructs aDate
object using the given milliseconds time value.
tips: 由于我们处于东八区,所以我们的基准时间为1970年1月1日8时0分0秒。
简单来说:使用无参构造,可以自动设置当前系统时间的毫秒时刻;
指定long类型的构造参数,可以自定义毫秒时刻
import java.util.Date;
public class Demo01Date {
public static void main(String[] args) {
// 创建日期对象,这个对象被初始化为当前的日期和时间
System.out.println(new Date()); // Tue Jan 16 14:37:35 CST 2018
// 创建日期对象,把当前的毫秒值转成日期对象
System.out.println(new Date(0L)); // Thu Jan 01 08:00:00 CST 1970
//把日期对象转换为毫秒值
System.out.println(new Date().getTime()); //1589631765140
}
}
tips:在使用println方法时,会自动调用Date类中的toString方法。Date类对Object类中的toString方法进行了覆盖重写,所以结果为指定格式的字符串。
2.2DateFormat类 --- 这是个抽象类
java.text.DateFormat
是日期/时间格式化子类的抽象类,我们通过这个类可以帮我们完成日期和文本之间的转换,也就是可以在Date对象与String对象之间进行来回转换。
- 格式化:按照指定的格式,从Date对象转换为String对象。
- 解析:按照指定的格式,从String对象转换为Date对象。
构造方法
由于DateFormat为抽象类,不能直接使用,所以需要常用的子类java.text.SimpleDateFormat
。这个类需要一个模式(格式)来指定格式化或解析的标准。构造方法为:
public SimpleDateFormat(String pattern)
:用给定的模式和默认语言环境的日期格式符号构造SimpleDateFormat。
参数pattern是一个字符串,代表日期时间的自定义格式。
格式规则
常用的格式规则为:
标识字母(区分大小写) | 含义 |
---|---|
y | 年 |
M | 月 |
d | 日 |
H | 时 |
m | 分 |
s | 秒 |
备注:更详细的格式规则,可以参考SimpleDateFormat类的API文档0。
常用方法
DateFormat类的常用方法有:
public String format(Date date)
:将Date对象格式化为日期-时间字符串。Formats aDate
into a date-time string.public Date parse(String source)
:将字符串解析为Date对象。
format方法
使用format方法的代码为:
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
/*
把Date对象转换成String
*/
public class Demo03DateFormatMethod {
public static void main(String[] args) {
Date date = new Date();
// 对应的日期格式如:2018-01-16 15:06:38
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String str = sdf.format(date);
System.out.println(date); //Sat May 16 20:43:31 GMT+08:00 2020
System.out.println(str); //2020-05-16 20:43:31
}
}
parse方法
使用parse方法的代码为:
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/*
把String转换成Date对象
*/
public class Demo04DateFormatMethod {
public static void main(String[] args) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
String str = "2018年12月11日";
Date date = sdf.parse(str);
System.out.println(date); // Tue Dec 11 00:00:00 GMT+08:00 2018
}
}
2.3LocalDate类
为什么会有LocalDate类?
因为Date类的实例是一个状态,即特定的时间点。Date类对于处理人类记录日期的日历信息
并不是很有用。
注意:不要使用构造器来构造LocalDate类的对象。-----使用静态工厂方法,它会代你调用构造器。
1: LocalDate.now() //表示构造这个对象是时的日期
2:可以提供 年,月,日来构造对应一个特定日期的对象
LocalDate.of(2020,12,25)
完成代码:
import java.time.LocalDate;
public class LocalDateTest {
public static void main(String[] args) {
LocalDate newYearsEve = LocalDate.of(2020,12,25);
int year = newYearsEve.getYear(); //2020
int month = newYearsEve.getMonthValue(); //12
int day = newYearsEve.getDayOfMonth() ; //25
//加1000天,返回得到一个新的对象
LocalDate aThounsandDatsLater = newYearsEve.plusDays(1000);
System.out.println(aThounsandDatsLater); //返回一个新的LocalDate对象 2023-09-21
year = aThounsandDatsLater.getYear(); //2023
month = aThounsandDatsLater.getMonthValue(); //9
day = aThounsandDatsLater.getDayOfMonth(); //21
System.out.println(year);
System.out.println(month);
System.out.println(day);
}
}
测试:下面的程序显示当前月的日历---参考java核心卷I P96
package day02;
import java.time.DayOfWeek;
import java.time.LocalDate;
/**
* Mon Tue Wed Thu Fri Sat Sun
* 1 2 3
* 4 5 6 7 8 9 10
* 11 12 13 14 15 16* 17
* 18 19 20 21 22 23 24
* 25 26 27 28 29 30 31
*
*
*
*
*/
public class CalendarTest {
public static void main(String[] args) {
//构造一个当前日期的对象
LocalDate date = LocalDate.now(); //2020-05-16
//获取当前的月份和日期
int month = date.getMonthValue(); //5
int today = date.getDayOfMonth(); //16
System.out.println(date);
//将date设置为这个月的第一天
date = date.minusDays(today-1); //2020-05-01 当前对象减去指定的天数 today-(today-1)
DayOfWeek weekday = date.getDayOfWeek();
int value = weekday.getValue(); // 5 代表星期五, 1=Monday,2020年5月1号是星期五
System.out.println(month);
System.out.println(today);
System.out.println(date);
System.out.println(value);
//日历的第一行是缩进的
System.out.println("Mon Tue Wed Thu Fri Sat Sun");
for (int i = 0; i < value; i++) {
System.out.print(" ");
}
//打印日历的主体
while (date.getMonthValue() == month){ //获取当前日期是第几月 getMonthValue()
System.out.printf("%3d",date.getDayOfMonth()); //getDayOfMonth()--得到当前日期的日和printf()
if (date.getDayOfMonth() == today){
System.out.print("*"); //print()不换行
}else{
System.out.print(" ");
}
date= date.plusDays(1); //日期+1天,返回一个新的LocalDate对象
if(date.getDayOfWeek().getValue() == 1 ) System.out.println(); //如果星期的值是1,就换行
}
if(date.getDayOfWeek().getValue() !=1) System.out.println();
}
}
2.4日期和时间API--java核心卷II P280
Java的Date和Time API规范要求Java使用的时间尺度为:
- 每天86400秒
- 每天正午与官方时间精确匹配
- 在其他时间点上,以精确定义的方式与官方时间接近匹配
2.4.1:
时间线--绝对时间
- Instant.now()从最佳的可用系统时间中获取当前的时刻
- Duration.between():得到两个时刻之间的时间差
# 度量一个算法的运行时间
Instant start = Instant.now();
runAlgorithm();
Instant end = Instant.now();
Durtion timeElapsed = Duration.between(start,end);
long millis = timeElapsed.tiMillis();
本地时间:
两种人类时间:
- 本地日期和时间: 包含日期和当前时间,但是与时区信息没有任何关联eg:2023-09-21
- 时区时间 [除非确实要表示绝对时间的实例] :时间线上一个精确的时刻 eg :Tue Jan 16 14:37:35 CST 2020
本地时间使用类LocalDate
两个Instant之间的时长是Duration,本地日期的时长则是Period,表示流逝的年|月|日数量
package day02;
import java.time.LocalDate;
import java.time.Month;
import java.time.Period;
import java.time.temporal.ChronoUnit;
public class LocalDateTest2 {
public static void main(String[] args) {
LocalDate date = LocalDate.now(); //今天的日期2020-05-16
LocalDate myBirthday = LocalDate.of(1903,6,14);
myBirthday = LocalDate.of(1903, Month.JUNE,14); //1903-06-14
System.out.println(date);
System.out.println(myBirthday);
//程序员日--外国平年9月13日,闰年9月12日,中国程序员日1024
LocalDate programmersDay = LocalDate.of(2020,1,1).plusDays(255);
System.out.println("programmersDay:"+ programmersDay);
//通过Period.ofyears(1):1年
myBirthday = myBirthday.plus(Period.ofYears(1)); //1904-06-14
myBirthday = myBirthday.plusYears(1); //1905-06-14
System.out.println(myBirthday);
//until会打印两个本地日期之间的时长
LocalDate independenceDay = LocalDate.of(2020,Month.JUNE,4);
LocalDate christmas= LocalDate.of(2020,12,25);
System.out.println("Until christmas: " +independenceDay.until(christmas, ChronoUnit.DAYS)); //计算两个日期之间出day数
System.out.println(LocalDate.of(2020,5,16).plusMonths(1)); //2020-06-16
System.out.println(LocalDate.of(2020,5,16).minusMonths(1)); //2020-04-16
}
}
日期调整
- 计算"每个月的第一个星期二"
package day02;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.temporal.TemporalAdjuster;
import java.time.temporal.TemporalAdjusters;
public class TemporaAdjustersTest {
public static void main(String[] args) {
//每个月的第一个星期二
LocalDate firstTuesday = LocalDate.of(2020,5,1).with(
TemporalAdjusters.nextOrSame(DayOfWeek.TUESDAY));
System.out.println(firstTuesday); //2020年5月的第一个星期二是2020-05-05号
}
}