write:2022-3-29
Object类
Object 类是所有Java类的最终祖先,如果一个类在声明时没有包含extends关键词,那么这个类直接继承Object类。
所有Java类都继承了Object类的方法,包括wait()、notify()、notifyall()、equals()和toString()等。
equals()
equals()方法的声明格式如下:public boolean equals(Object obj)
Object类的equals()方法的比较规则为:当参数obj引用的对象与当前对象为同一个对象,就返回true,否则返回false:
public boolean equals(Object obj){
if(this==obj)return true;
else return false;
}
演示代码:
Animal animal1=new Dog();
Animal animal2=new Cat();
Animal animal3=animal1;
System.out.println(animal1 == animal2); //打印false
System.out.println(animal1.equals(animal2)); //打印false
System.out.println(animal1 == animal3); //打印true
System.out.println(animal1.equals(animal3)); //打印true
在JDK中有一些类覆盖了Object类的equals()方法,它们的比较规则为:如果两个对象的类型一致,并且内容一致,则返回true。
这些类主要包括:java.io.File、java.util.Date、java.lang.String、包装类(如java.lang.Integer和java.lang.Double类)。
演示代码:
Integer int1=new Integer(1);
Integer int2=new Integer(1);
String str1=new String(“Hello”);
String str2=new String(“Hello”);
System.out.println(int1==int2); //打印false
System.out.println(int1.equals(int2)); //打印true
System.out.println(str1==str2); //打印false
System.out.println(str1.equals(str2)); //打印true
在用户自定义的类中也可以覆盖Object类的equals()方法,重新定义比较规则。
演示代码:
import java.util.Objects;
public class Person {
private String name;
public Person(String name) {
this.name = name;
}
public boolean equals(Object o){
if(thiso)return true;
if(!(o instanceof Person)) return false;
final Person other=(Person)o;
if(this.name .equals(other.name))
return true;
else
return false;
}
public static void main(String[] args) {
Person person1=new Person(“Tom”);
Person person2=new Person(“Tom”);
System.out.println(person1person2); //打印false
System.out.println(person1.equals(person2)); //打印true
}
}
toString()
toString()返回当前对象的字符串表示,格式为“类名@对象的16进制哈希码”。
许多类,如String、StringBuffer和包装类都覆盖了toString()方法,返回具有实际意义的内容。
System.out.println(new Object().toString()); //打印java.lang.Object@273d3c
System.out.println(new Integer(100).toString()); //打印100
System.out.println(new String(“123”).toString()); //打印123
System.out.println(new StringBuffer(“123456”).toString()); //打印123456
以上代码等价于:
System.out.println(new Object());
System.out.println(new Integer(100));
System.out.println(new String(“123”));
System.out.println(new StringBuffer(“123456”));
当System.out.println()方法的参数为Object类型,println()方法会自动先调用Object对象的toString()方法,然后打印toString()方法返回的字符串。
length()
length():返回字符串的字符个数。
charAt(int index)
char charAt(in index):返回字符串中index位置上的字符,其中index的取值范围是“0 ~ 字符串长度-1”。
equalsIgnoreCase(Object str)
equals(object str)和equalsIgnoreCase(object str):判断两个字符串对象的内容是否相同。两个方法的区别在于:equalsIgnoreCase()方法不区分字母的大小写,而equals()方法则须区分字母的大小写。
String s1=“hello”;
String s2=“h”+“ello”;
String s3=“Hello”;
System.out.println(s1.equals(s2)); //打印true
System.out.println(s1.equals(s3)); //打印false
System.out.println(s1.equalsIgnoreCase(s3)); //打印true
compareTo(String str)
int compareTo(String str):按字典次序比较两个字符串的大小。如果源串较小,则返回一个小于0的值,如相等则返回0,否则返回一个大于0的值。例如:
System.out.println(“a”.compareTo(“b”)); //打印-1
System.out.println(“a”.compareTo(“a”)); //打印0
System.out.println(“b”.compareTo(“a”)); //打印1
indexOf()
indexOf() :在字符串中检索特定字符或子字符串,indexOf()方法从字符串的首位开始查找。如果找到,则返回匹配成功的位置,如果没有找到,则返回-1。
String str=“HelloHelloHello”;
//查找字符’e’第一次在str中出现的位置
System.out.println(str.indexOf(‘e’)); //打印1
//查找字符’e’从位置2开始第一次在str中出现的位置
System.out.println(str.indexOf(‘e’,2)); //打印6
//查找字符串"ello"从位置2开始第一次在str中出现的位置
System.out.println(str.indexOf(“ello”,2)); //打印6
//查找字符串"Ello"第一次在str中出现的位置
System.out.println(str.indexOf(“Ello”)); //不存在则打印-1
concat(String str)
concat(String str):把字符串str附加在当前字符串的末尾。例如:
String str=“Hello”;
String newStr=str.concat(“World”);
System.out.println(str); //打印Hello(str本身的内容并不会发生改变)
System.out.println(newStr); //打印HelloWorld
以上concat()方法并不会改变字符串str本身的内容。
substring()
substring():返回字符串的一个子字符串,有以下两种重载形式:
public String substring(int beginIndex)
public String substring(int beginIndex, int endIndex) (左闭右开)
子串在源串中的起始位置为beginIndex,结束位置为endIndex-1。如果没有提供endIndex参数,那么结束位置为:字符串长度-1。
String str=“0123456”;
String sub1=str.substring(2);
String sub2=str.substring(2,5);
System.out.println(str); //打印0123456
System.out.println(sub1); //打印23456
System.out.println(sub2); //打印234
String类与StringBuffer类
StringBuffer类表示字符串缓存,它有以下构造方法:
(1)StringBuffer():建立一个空的缓冲区,初始容量为16个字符。
(2)StringBuffer(int length):建立一个初始容量为length的空缓冲区。
(3)StringBuffer(String str):缓冲区的初始内容为字符串str,并另外提供16个字符的初始容量。
length()
length():返回字符串的字符个数,与String类的length()用法相同。
append()
append():向缓冲区内添加新的字符串,例如:
StringBuffer sb=new StringBuffer();
sb.append(“Hello”);
sb.append(“World”);
System.out.println(sb); //打印HelloWorld
substring()
substring():用法与String类的substring()方法相同。
insert( int offset, String str)
insert( int offset, String str):在字符串中的offset位置插入字符串str,例如:
StringBuffer sb=new StringBuffer(“0456”);
sb.insert(1,“123”);
System.out.println(sb); //打印0123456
String类和StringBuffer类的区别
String类是不可变类,而StringBuffer类是可变类。
String对象创建后,它的内容无法改变。一些看起来能够改变字符串的方法,实际上是创建一个带有方法所赋予特性的新字符串。例如String类的substring()和concat() 等方法都不会改变字符串本身,而是创建并返回一个包含改变后内容的新字符串对象。
StringBuffer的append()和insert() 等方法都会改变字符缓冲区中的字符串内容。
String s=new String(“abc”);
StringBuffer sb=new StringBuffer(“abc”);
s.concat(“def”); //连接字符串“def”
sb.append(“def”); //添加字符串“def”
System.out.println(s); //打印abc
System.out.println(sb); //打印abcdef
包装类
Java语言用包装类来把基本类型数据转换为对象。每个Java基本类型在java.lang包中都有一个相应的包装类。
包装类的作用:包装类中提供了一系列实用的方法,比如Integer类的静态方法parseInt(String s)能把字符串转换为整数,静态方法toBinaryString(int i)返回包含整数i的二进制形式的字符串。
包装类的特点
所有的包装类都是final类型,因此不能创建它们的子类。
包装类是不可变类,一个包装类的对象自创建后,它所包含的基本类型数据就不能被改变。
包装类的层次结构
Character类和Boolean类直接继承Object类,除此以外,其他包装类都是java.lang.Number类的直接子类,因此都继承或者覆盖了Number类的方法。
包装类的方法
- toString():包装类都覆盖了Object类的toString()方法,以字符串的形式返回包装对象所表示的基本类型数据。
- valueOf(String s):除Character类和Boolean类以外,包装类都有valueOf(String s)静态工厂方法,可以根据String类型的参数来创建包装类对象。参数字符串s不能为null,而且该字符串必须可以解析为相应的基本类型的数据,否则虽然编译会通过,运行时会抛出NumberFormatException。
Double d=Double.valueOf(“123”); //合法
Integer i=Integer.valuesOf(“12”); //合法
Integer i=Integer.valuesOf(“abc”); //运行时抛出NumberFormatException - parseXXX(String str):除Character类和Boolean类以外,包装类都有parseXXX(String str)静态方法,把字符串转变为相应的基本类型的数据(XXX表示基本类型的名称)。参数str不能为null,而且该字符串必须可以解析为相应的基本类型的数据,否则虽然编译会通过,运行时会抛出NumberFormatException。
int i=Integer.parseInt(“123”); //合法,i=123
double d=Double.parseDouble(“abc”); //抛出NumberFormatException
包装类的自动装箱与拆箱
在JDK5以前的版本中,数学运算表达式中操作元必须是基本类型,并且运算结果也是基本类型,例如:
int a=1,b;
b=a+1-24; //合法
Integer c=a+1-24; //编译出错,运算结果必须是基本类型
b=a+Integer.valueOf(1)-Integer.valueOf(2)*4; //编译出错,操作元必须是基本类型
而在JDK5以上版本中,允许基本类型和包装类型进行混合数学运算,因此以上都是合法的表达式。
把基本类型转换为包装类型的过程称为装箱,把包装类型还原成基本类型的过程称为拆箱。以下是两段合法的赋值语句:
Integer a=3; //自动装箱,把3包装成Integer对象。
int b=new Integer(4); //自动拆箱,把Integer对象还原成基本类型。
Math类
java.lang.Math 类提供了许多用于数学运算的静态方法,包括指数运算、对数运算、平方根运算和三角运算等。
Math类还有两个静态常量:E(自然对数)和PI(圆周率)。
Math类是final类型的,因此不能有子类。
Math类的构造方法是private类型的,因此Math类不能够被实例化。
Math的方法
abs():返回绝对值。
ceil():返回大于等于参数的最小整数。
floor():返回小于等于参数的最大整数。
max():返回两个参数的较大值。
min():返回两个参数的较小值。
random():返回0.0和1.0 之间的double类型的随机数,包括0.0,但不包括1.0。
round():返回四舍五入的整数值。
sin():正弦函数。
cos():余弦函数。
tan():正切函数。
exp():返回自然对数的幂。
sqrt():平方根函数。
pow():幂运算。
System.out.println(Math.round(3.3)); //打印3
System.out.println(Math.round(-3.3)); //打印-3
System.out.println(Math.ceil(3.3)); //打印4.0
System.out.println(Math.ceil(-3.3)); //打印-3.0
System.out.println(Math.floor(3.3)); //打印3.0
System.out.println(Math.floor(-3.3)); //打印-4.0
Random类
java.util.Random类提供了一系列用于生成随机数的方法:
nextInt():返回下一个int类型的随机数,随机数的值大于等于0。
nextInt(int n) :返回下一个int类型的随机数,随机数的值大于等于0,并且小于参数n。
nextLong():返回下一个long类型的随机数,随机数的值位于long类型的取值范围内。
nextFloat():返回下一个float类型的随机数,随机数的值大于等于0,并且小于1.0。
nextDouble():返回下一个double类型的随机数, 随机数的值大于等于0,并且小于1.0。
nextBoolean():返回下一个boolean类型的随机数,随机数的值为true或false。
Random r=new Random();
//生成10个int类型的随机数,取值在0到100之间
for(int i=0;i<10;i++)System.out.print(r.nextInt(100)+" “);
System.out.println();
//生成3个long类型的随机数
for(int i=0;i<3;i++)System.out.print(r.nextLong()+” “);
System.out.println();
//生成3个double类型的随机数,取值在0.0到100.0之间
for(int i=0;i<3;i++)
System.out.print(r.nextDouble()*100+” ");
日期/时间类
java.time.LocalDate
java.time.LocalDate类表示日期,是一个不可变的类,它的默认格式为“yyyy-MM-dd”。
LocalDate类的一些静态工厂方法(例如now()方法和of()方法等)负责创建LocalDate对象。
eg:
package UsageOfJavaApi;
import java.time.LocalDate;
import java.time.Month;
import java.time.ZoneId;
public class LocalDateSample {
public static void main(String[] args) {
//当前日期
LocalDate today = LocalDate.now();
System.out.println("当前日期:"+today);
//根据特定的参数创建LocalDate对象
LocalDate firstDay_2016 = LocalDate.of(2016, Month.JANUARY,1);
System.out.println("特定的日期:"+firstDay_2016);
//获得欧洲巴黎的当前日期
LocalDate todayPairs = LocalDate.now(ZoneId.of("Europe/Paris"));
System.out.println("巴黎的当前日期:"+todayPairs);
//根据基准日1970-01-01开始算起的日期
LocalDate dateFromBase = LocalDate.ofEpochDay(365);
System.out.println("从1970/1/1起相隔365天的日期:"+dateFromBase);
//从特定年份开始算起的日期
LocalDate hundredDay2016 = LocalDate.ofYearDay(2016,100);
System.out.println("2016年的第一百天:"+hundredDay2016);
}
}
运行结果:
java.time.LocalTime
java.time.LocalTime类表示时间,是一个不可变的类,它的默认格式为“hh:mm:ss.zzz”。
LocalTime类的一些静态工厂方法(例如now()方法和of()方法等)负责创建LocalTime对象。
eg:
package UsageOfJavaApi;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.Month;
import java.time.ZoneId;
public class LocalTimeSample {
public static void main(String[] args) {
//当前时间
LocalTime time = LocalTime.now();
System.out.println("当前时间:"+time);
//根据特定的参数创建LocalTime对象
LocalTime specificTime = LocalTime.of(12,20,25,40);//40是纳秒
System.out.println("特定的时间:"+specificTime);
//获得欧洲巴黎的当前时间
LocalTime timePairs = LocalTime.now(ZoneId.of("Europe/Paris"));
System.out.println("巴黎的当前时间:"+timePairs);
//以“00:00:00”为基准,根据参数指定的秒数开始计算时间
LocalTime specificSecondTime = LocalTime.ofSecondOfDay(60*60*3+60*15+44);
System.out.println("经过特定秒数后的时间:"+specificSecondTime);
}
}
运行结果:
java.time.LocalDateTime
java.time.LocalDateTime类表示日期时间,是一个不可变的类,它的默认格式为“yyyy-MM-dd T HH-mm-ss.zzz”。
LocalDateTime类的一些静态工厂方法(例如now()方法和of()方法等)负责创建LocalDateTime对象。
eg:
package UsageOfJavaApi;
import java.time.*;
public class LocalDateTimeSample {
public static void main(String[] args) {
//当前日期时间
LocalDateTime today = LocalDateTime.now();
System.out.println("当前日期时间:"+today);
today = LocalDateTime.of(LocalDate.now(), LocalTime.now());
System.out.println("当前日期时间:"+today);
//根据特定的参数创建LocalDateTime对象
LocalDateTime specificDate = LocalDateTime.of(2016, Month.JANUARY,1,10,20,30);
System.out.println("特定日期时间:"+specificDate);
//获得欧洲巴黎的当前日期时间
LocalDateTime todyPairs = LocalDateTime.now(ZoneId.of("Europe/Paris"));
System.out.println("巴黎的当前日期时间:"+todyPairs);
//以“1970-1-1 00:00:00”为基准,计算经过特定秒数后的日期时间
LocalDateTime dateFromBase = LocalDateTime.ofEpochSecond(1000,0,ZoneOffset.UTC);//三个参数分别代表:秒,纳秒,时差
System.out.println("经过特定秒数后的日期时间:"+dateFromBase);
}
}
运行结果:
课堂小结
- Object 类是所有Java类的最终祖先,如果一个类在声明时没有包含extends关键词,则编译器创建一个从Object 派生的类;
- String类和包装类都是不可变类,而StringBuffer类是可变类。
String、StringBuffer和包装类都重写了toString()方法,返回对象包含内容的字符串表示。 - 所有的包装类都可以用和它对应的基本类型数据为参数,来构造它们的实例。
除Character类和Boolean类以外,包装类都有parseXXX(String str)静态方法,把str字符串转变为相应的基本类型的数据(XXX表示基本数据类型的名称)。参数str不能为null,而且必须可以解析为相应的基本类型的数据,否则虽然编译会通过,但运行时会抛出NumberFormatException。
所有的包装类都是final的,因此没有子类。 - Math类是final的,因此没有子类。
Math类的构造方法是private的,因此Math 不能够被实例化。
Math类提供的方法都是静态的,可以通过类名直接调用。