第1关:Object类
Java
中有一个比较特殊的类,就是 Object
类,它是所有类的父类,如果一个类没有使用extends
关键字明确标识继承另外一个类,那么这个类就默认继承 Object
类。因此,Object
类是 Java 类层中的最高层类,是所有类的超类。换句话说,Java 中任何一个类都是它的子类。由于所有的类都是由 Object
类衍生出来的,所以 Object
类中的方法适用于所有类。
1.关于toString()
方法
在Object
类里面定义toString()
方法的时候返回的对象的哈希code
码(对象地址字符串);
可以通过重写toString()
方法表示出对象的属性。
2.关于equals()
方法
比较的是对象的引用是否指向同一块内存地址,一般情况下,比较两个对象时是比较它的值是否一致,那如何解决呢?思路也比较简单,重写equals()
方法。
在不重写的情况下,我们先看下程序执行情况,创建两个相同类型的对象,并判断对象是否相等。
equals()
和 ==
的区别:
- 在Java中,任何类型的数据都可以用 “==”进行比较是不是相等,一般用于基本数据类型的比较,比较器存储的值是否相等。但是如果用于引用类型的比较,则是比较所指向对象的地址是否相等,在这点上,跟
object
类提供的equals()
方法的作用是一致的。 - 对于
equals()
方法
首先,不能用于基本数据类型的变量之间的比较相等;
如果没有对equals
方法进行重写,则比较的是引用类型的变量所指向的对象的地址;
诸如String
、Date
等类都对equals
方法进行了重写,比较的是所指向的对象的内容。
Java对象克隆(目的是:少处理任务)
对象克隆是一种创建对象的精确副本的方法。 Object
类的clone()
方法用于克隆对象。java.lang.Cloneable
接口必须由我们要创建其对象克隆的类实现。如果我们不实现Cloneable
接口,clone()
方法将生成CloneNotSupportedException
package case1;
import java.util.Scanner;
public class ObjectTest {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int num1 = sc.nextInt();
int num2 = sc.nextInt();
// 在测试类中创建Demo类对象d1,传入输入值num1, d1调用toString方法并打印输出该值
// 创建Demo类对象d2,同样传入输入值num1,打印判断d1和d2是否相等(实际是比较地址)
/********* Begin *********/
Demo d1 = new Demo(num1);
System.out.println(d1.toString());
Demo d2 = new Demo(num1);
System.out.println(d1.equals(d2));
/********* End *********/
// 创建Person类对象p,传入输入值num2,打印判断d1和p是否相等(实际比较地址)
/********* Begin *********/
Person p1 = new Person(num2);
System.out.println(p1.equals(d1));
/********* End *********/
}
}
class Demo {
private int num;
public Demo(int num) {
this.num = num;
}
public boolean equals(Object obj) // Object obj = new Demo()
{
if (!(obj instanceof Demo)) // 判断obj是否和Demo是同类
return false;
Demo d = (Demo) obj; // 将父类的引用(Object)向下转换为子类(Demo)
return this.num == d.num;
}
public String toString() {
return "Demo:" + num; // 返回对象的值(每一个对象都有自己的特定的字符串)
}
}
class Person {
private int num;
public Person(int num) {
this.num = num;
}
}
第2关:字符串类练习
/*
https://www.educoder.net/->educoder EDUCODER
https://www.sina.com.cn/->sina SINA
*/
package case3;
import java.util.*;
public class StringTest {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str = sc.next();
// String substring(int start,int end)
// 截取字符串,传入的两个参数分别为要截取边界的下标
// 在java api 中,通常使用两个数字表示范围时,都是含头不含尾,即包含起始下标对应的内容,但不包含结束下标的处对应的内容
// String toUpperCase() 将当前字符串中的英文部分转换为全大写
/********* Begin *********/
int a=str.indexOf('.');
int b=str.length();
str=str.substring(a+1,b);
a=str.indexOf('.');
str=str.substring(0,a);
System.out.println(str);
System.out.println(str.toUpperCase());
/********* End *********/
}
}
第3关:JAVA基础类型包装类-练习
为什么Integer用"=="会是true的问题
参考:包装类及基本数据类型之间大小比较_不问世事的码农-CSDN博客
package case2;
import java.util.Scanner;
public class WrapperTest {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int aa = sc.nextInt();
String bb = sc.next();
String str11 = sc.next();//100
String str22 = sc.next();//100
// 包装类中“==”与equals的用法比较
// 值得注意的是,包装类中的equals方法和String类一样,都是重写了Object类中的equals方法,因此比较的是内容而不是地址,
// 而“==”比较的依然是引用变量的地址,只是当包装类型和与之相对应的基本类型进行“==”比较时会先做自动拆箱处理。
/********* Begin *********/
int c = sc.nextInt();//100
Integer a=new Integer(aa);
Integer b=new Integer(bb);
System.out.println(a==b);//false
System.out.println(a==c);//true
System.out.println(c==b);//true
System.out.println(a.equals(b));//true
String str1=new String(str11);//EDU
String str2=new String(str22);//EDU
System.out.println(str1==str2);//false
System.out.println(str1.equals(str2));//true
/********* End *********/
}
}
第4关:Math类
Math类是一个工具类,它的构造器被定义成
private的,因此无法创造
Math类的对象。
Math类中所有的方法都是类方法,可以直接通过类名来调用他们。
Math类包含完成基本数学函数所需的方法。这些方法基本可以分为三类:三角函数方法、指数函数方法和服务方法。在
Math类中定义了
PI和
E两个
double型常量,
PI就是
π的值,而
E即
e指数底的值,分别是:
3.141592653589793和
2.718281828459045
Math
类中常用方法
- 三角函数方法;
Math
类包含下面的三角函数方法:
-
Math.toDegrees
这个方法是将
-π/2
到π/2
之间的弧度值转化为度,例如:Math.toDegrees(Math.PI/2)
结果为90.0
; -
Math.toRadians
这个方法是将度转化为-π/2
到π/2
之间的弧度值,例如:Math.toRadians(30)
结果为π/6
;
-
Math.sin
、Math.cos
、Math.tan
这三个方法是三角函数中的正弦、余弦和正切,反之Math.asin
、Math.acos
、Math.atan
是他们的反函数。 -
指数函数方法;
Math
类中有五个与指数函数相关的方法Math.exp(a)
方法主要是获得以 e 为底 a 为指数的数值;Math.log()
和Math.log10()
是对数函数;Math.pow(a,b)
是以a为底b为指数的值;Math.sqrt()
是开根号。
- 取整方法;
Math
类里包含五个取整方法:Math.ceil()
方法是往大里取值;Math.floor()
方法是往小里取值;Math.rint()
方法返回与参数最接近的整数,返回类型为double
,注意.5
的时候会取偶数;Math.round()
方法分两种:int
型和long
型,Math.round(a)
就是Math.floor(a+0.5)
,即将原来的数字加上0.5
后再向下取整,所以,Math.round(11.5)
的结果为12
,Math.round(-11.5)
的结果为-11
。
-
min
、max
和abs
方法
取最大值和最小值以及绝对值。
-
random
方法。
生成随机数取值范围是0.0
到1.0
的double
型数值。也可以用简单的表达式生成任意范围的随机数,例如: (int)(Math.random()*10)
返回0
到9
之间的一个随机整数。
接下来通过一个具体的实例进一步了解Math
类的常用方法:
package educoder;
public class MathTest{
public static void main(String args[]){
/**
*Math.sqrt()//计算平方根
*Math.cbrt()//计算立方根
*Math.pow(a, b)//计算a的b次方
*Math.max( , );//计算最大值
*Math.min( , );//计算最小值
*/
System.out.println(Math.sqrt(16)); //4.0
System.out.println(Math.cbrt(8)); //2.0
System.out.println(Math.pow(3,2)); //9.0
System.out.println(Math.max(2.3,4.5));//4.5
System.out.println(Math.min(2.3,4.5));//2.3
/**
* abs求绝对值
*/
System.out.println(Math.abs(-10.4)); //10.4
System.out.println(Math.abs(10.1)); //10.1
/**
* ceil天花板的意思,就是返回大的值
*/
System.out.println(Math.ceil(-10.1)); //-10.0
System.out.println(Math.ceil(10.7)); //11.0
System.out.println(Math.ceil(-0.7)); //-0.0
System.out.println(Math.ceil(0.0)); //0.0
System.out.println(Math.ceil(-0.0)); //-0.0
System.out.println(Math.ceil(-1.7)); //-1.0
/**
* floor地板的意思,就是返回小的值
*/
System.out.println(Math.floor(-10.1)); //-11.0
System.out.println(Math.floor(10.7)); //10.0
System.out.println(Math.floor(-0.7)); //-1.0
System.out.println(Math.floor(0.0)); //0.0
System.out.println(Math.floor(-0.0)); //-0.0
/**
* random 取得一个大于或者等于0.0小于不等于1.0的随机数
*/
System.out.println(Math.random()); //小于1大于0的double类型的数
System.out.println(Math.random()*2);//大于0小于1的double类型的数
System.out.println(Math.random()*2+1);//大于1小于2的double类型的数
/**
* rint 四舍五入,返回double值
* 注意.5的时候会取偶数
*/
System.out.println(Math.rint(10.1)); //10.0
System.out.println(Math.rint(10.7)); //11.0
System.out.println(Math.rint(11.5)); //12.0
System.out.println(Math.rint(10.5)); //10.0
System.out.println(Math.rint(10.51)); //11.0
System.out.println(Math.rint(-10.5)); //-10.0
System.out.println(Math.rint(-11.5)); //-12.0
System.out.println(Math.rint(-10.51)); //-11.0
System.out.println(Math.rint(-10.6)); //-11.0
System.out.println(Math.rint(-10.2)); //-10.0
/**
* round 四舍五入,float时返回int值,double时返回long值
*/
System.out.println(Math.round(10.1)); //10
System.out.println(Math.round(10.7)); //11
System.out.println(Math.round(10.5)); //11
System.out.println(Math.round(10.51)); //11
System.out.println(Math.round(-10.5)); //-10
System.out.println(Math.round(-10.51)); //-11
System.out.println(Math.round(-10.6)); //-11
System.out.println(Math.round(-10.2)); //-10
}
}
第5关:Random类
Random类
Random
类位于java.util
包下,Random
类中实现的随机算法是伪随机,也就是有规则的随机。在进行随机时,随机算法的起源数字称为种子数(seed
),在种子数的基础上进行一定的变换,从而产生需要的随机数字。
相同种子数的Random
对象,相同次数生成的随机数字是完全相同的。也就是说,两个种子数相同的Random
对象,第一次生成的随机数字完全相同,第二次生成的随机数字也完全相同。这点在生成多个随机数字时需要特别注意。
Random对象的生成 Random
类包含两个构造方法,下面依次进行介绍:
public Random()
该构造方法使用一个和当前系统时间对应的相对时间有关的数字作为种子数,然后使用这个种子数构造Random
对象。
public Random(long seed)
该构造方法可以通过制定一个种子数进行创建。
示例代码:
Random r = new Random();Random r1 = new Random(10);
再次强调:种子数只是随机算法的起源数字,和生成的随机数字的区间无关。
验证:相同种子数的Random
对象,相同次数生成的随机数字是完全相同的。
package case4;
//密码的自动生成器:密码由大写字母/小写字母/数字组成,生成六位随机密码
import java.util.*;
public class RandomTest {
public static void main(String[] args) {
// 定义一个字符型数组
char[] pardStore = new char[62];
// 把所有的大写字母放进去 把所有的小写字母放进去 把0到9放进去
/********* Begin *********/
for(int i=0;i<26;i++){
pardStore[i]=(char)('A'+i);
}
for(int i=26;i<52;i++){
pardStore[i]=(char)('a'+(i-26));
}
for(int i=52;i<62;i++){
pardStore[i]=(char)('0'+(i-52));
}
/********* End *********/
// 分别以1、2、3作为种子数 生成6位随机密码
Scanner sc = new Scanner(System.in);
int seed = sc.nextInt();
/********* Begin *********/
Random r=new Random(seed);
for(int i=0;i<6;i++){
int n=r.nextInt(62);
System.out.print(pardStore[n]);
}
/********* End *********/
}
}
第6关:Date类和SimpleDateFormat类的用法
Java日期时间
java.util
包提供了Date
类来封装当前的日期和时间。Date
类提供两个构造函数来实例化Date
对象。
第一个构造函数使用当前日期和时间来初始化对象。
Date( )
第二个构造函数接收一个参数,该参数是从1970年1月1日起的毫秒数。
Date(long millisec)
package case5;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
public class DateTest {
public static void main(String[] args) throws ParseException {
// 键盘录入你的出生年月日 格式为yyyy-MM-dd
// 把该字符串转换为一个日期
// 通过该日期得到一个毫秒值
// 获取2020年10月1日的毫秒值
// 两者想减得到一个毫秒值
// 把该毫秒值转换为天 打印输出
Scanner sc = new Scanner(System.in);
String line = sc.nextLine();
/********* Begin *********/
// 将字符串转为date类型
SimpleDateFormat StoDate=new SimpleDateFormat("yyyy-MM-dd");
Date birthdayDate=StoDate.parse(line);
// 获取当前日期
Date nowDate=StoDate.parse("2020-10-01");
// 转为毫秒值换算
long nowSecond=nowDate.getTime();
long birthdaySecond=birthdayDate.getTime();
long second=nowSecond-birthdaySecond;
System.out.println("你的出生日期距离2020年10月1日:"+second/1000/60/60/24+"天");
/********* End *********/
}
}