方法名 | 说明 |
---|---|
public static int abs(int a) | 返回参数的绝对值 |
public static double ceil(double a) | 返回大于或等于参数的最小double值,等于一个整数(向上取) |
public static double floor(double a) | 返回小于或等于参数的最大double值,等于一个整数(向下取) |
public static int round(float a) | 按照四舍五入返回最接近参数的int |
public static int max(int a, int b) | 返回两个int值中的较大值 |
public static int min(int a, int b) | 返回两个int值中的较小值 |
public static double pow(double a, double b) | 返回a的b次幂的值 |
public static double random() | 返回值为double的正值(随机数),[0.0,1.0) |
根据英文来记方法名:absolute绝对的,round把(数字)四舍五入,maximum最大的,minimum最小的,power次方/幂,random随机的
public class MathDemo {
public static void main(String[] args) {
System.out.println(Math.abs(3));//3
System.out.println(Math.abs(-3));//3
System.out.println(Math.abs(-3.3));//3.3
System.out.println(Math.ceil(4));//4.0
System.out.println(Math.ceil(4.3));//5.0
System.out.println(Math.ceil(-4.3));//-4.0
System.out.println(Math.floor(4));//4.0
System.out.println(Math.floor(4.3));//4.0
System.out.println(Math.floor(-4.3));//-5.0
System.out.println(Math.round(3.2));//3
System.out.println(Math.round(-3.2));//-3
System.out.println(3.5);//4
System.out.println(Math.max(22,11));//22
System.out.println(Math.max(1.1,1.3));//1.3
System.out.println(Math.max(1,1));//1
System.out.println(Math.min(22,11));//11
System.out.println(Math.min(1.1,1.3));//1.1
System.out.println(Math.min(-1,1));//-1
System.out.println(Math.pow(2,3));//8.0
System.out.println(Math.pow(2.3,3.3));
System.out.println(Math.random());//生成[0,1)的随机数
System.out.println((int)(Math.random()*100 + 1));//生成[0,100]的随机整数
}
}
方法名 | 说明 |
---|---|
public static void exit(int status) | 终止当前运行的Java虚拟机,非0表示异常终止 |
public static long currentTimeMillis() | 返回当前时间(以毫秒为单位) |
public static void main(String[] args) {
System.out.println("开始");
System.exit(0);
System.out.println("结束");//控制台并没有输出结束
}
public static void main(String[] args) {
System.out.println(System.currentTimeMillis());
//由于整数相除只能得到整数,为了更精确,我们除以1.0将结果变为浮点数。结果为1970年到现在经过的年数
System.out.println(System.currentTimeMillis() / 1.0 / 1000 / 60 / 60 / 24 / 365);
long start = System.currentTimeMillis();
for (int i=0; i<1000; i++){
System.out.println(i);
}
long end = System.currentTimeMillis();
System.out.println("程序共耗时:"+ (end-start) + "毫秒");
}
方法名 | 说明 |
---|---|
public String toString() | 返回对象的字符串表示形式。建议所有子类重写该方法,Alt+Insert自动生成即可 |
public boolean equals(Object obj) | 比较对象是否相等。默认比较地址值,重写可以比较内容,自动生成 |
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
........................
public class ObecjtDemo {
public static void main(String[] args) {
Student s = new Student();
s.setName("zjl");
s.setAge(22);
System.out.println(s);
}
}
最终结果输出itheima1.Student@1540e19d,我们更想输出一个与s对象有关系的数据,可是现在输出的字符串对我们没什么意义。这个字符串是怎么实现的呢?我们通过Ctrl+B查看println方法的实现:
public void println(Object x) {
String s = String.valueOf(x);
synchronized (this) {
print(s);
newLine();
}
}
在输出字符串前对象x(对象x即我们传入的对象s)调用了一个方法valueOf,我们继续查看该方法的实现:
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
这里面对象obj(对象obj即我们传入的对象s)调用了一个toString方法,我们继续查看该方法的实现:
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
原来println方法根据我们传入的对象,返回了类的全路径名(itheima1.Student@1540e19d前面带包名部分的内容)+@+hashCode。至此,我们可以知道,println(s)底层调用的是一个toString方法输出了一列字符串。我们Student底层并没有toString方法,所以继承了Object的,此时我们可以直接:System.out.println(s.toString()),发现输出结果也是itheima1.Student@1540e19d。
那么toString方法为什么要输出这样的内容呢?通过查看帮助文档,我们知道:toString方法返回对象的字符串表示形式。一般来说,toString方法返回一个代表这个对象的字符串。结果应该是一个简明扼要的表达,容易让人阅读。
但是现在的结果并不利于阅读,而文档也说了,建议所有子类重写该方法。重写方法:alt+insert,选择toString即可。
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public class ObectDemo {
public static void main(String[] args) {
Student s1 = new Student();
s1.setName("zjl");
s1.setAge(22);
Student s2 = new Student("zjl",22);
System.out.println(s1.equals(s2));//false
}
}
可我们使用了equals比较还是返回false,这是为什么呢?我们Ctrl+B查看equals方法的源码。
public boolean equals(Object obj) {
//this --- s1(谁调用此方法谁就是this)
//obj --- s2
return (this == obj);
}
这时候我们发现了再Object类中,equals方法其实本质上就是“==”。在这种情况下,我们可以重写equals方法。重写方法:alt+insert,选择equals() and hashCode(),在第一个界面选择Default的模板finish,然后删掉hashCode()即可。下为重写的equals方法的逻辑解析。
@Override
public boolean equals(Object o) {
/* this --- s1
o --- s2
比较的是地址是否相同,如果相同直接放回true */
if (this == o) return true;
//首先判断参数是否为null;然后判断两个对象是否来自于同一个类(通过获取对象的字解码文件)
if (o == null || getClass() != o.getClass()) return false;
//向下转型,student = s2
Student student = (Student) o;
//比较年龄是否相同,age隐含了this
if (age != student.age) return false;
//比较姓名是否相同,此处equals为String重写的equals方法,比较的是字符转的内容是否相同
return name != null ? name.equals(student.name) : student.name == null;
}
public class ArrayDemo {
public static void main(String[] args) {
//定义一个数组
int[] arr = {24, 69, 80, 57, 13};
System.out.println("排序前:" + arrayToString(arr));
array(arr);
System.out.println("排序前:" + arrayToString(arr));
}
public static void array(int[] arr) {
int temp;
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length - 1 -i; j++) {
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
//把数组中的元素按照指定的规则组成一个字符串:[元素1,元素2……]
public static String arrayToString(int[] arr) {
StringBuffer sb = new StringBuffer();
sb.append("[");
for (int i = 0; i < arr.length; i++) {
if (i == arr.length - 1) {
sb.append(arr[i]);
} else {
sb.append(arr[i]).append(",");
}
}
sb.append("]");
String s = sb.toString();
return s;
}
}
方法名 | 说明 |
---|---|
public static String toString(int[] a) | 返回指定数组的内容的字符串表示形式 |
public static void sort(int[] a) | 按照数字顺序排序列指定的数组 |
public class ArrayDemo2 {
public static void main(String[] args) {
int[] arr = {24, 69, 80, 57, 13};
System.out.println("排序前:" + Arrays.toString(arr));
Arrays.sort(arr);
System.out.println("排序后:" + Arrays.toString(arr));
}
}
基本数据类型 | 包装类 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
方法名 | 说明 |
---|---|
public Integer(int value) | 根据int值创建Integer对象(过时) |
public Integer(String s) | 根据String值创建Integer对象(过时) |
public static Integer value(int i) | 返回表示指定int值的Integer实例 |
public static Integer valueOf(String s) | 返回一个保存指定String值的Integer对象 |
注意:
(1)传入的String类型的字符串s必须要是以数字组成,否则会报错NumberFormatException。
(2)构造方法已过时,虽然继续使用也没问题,但是还是推荐后两种方式生成Integer实例。
public class IntegerDemo {
public static void main(String[] args) {
Integer i1 = new Integer(100);//过时
System.out.println(i1);
Integer i2 = new Integer("11");//过时
// Integer i2 =new Integer("abc");//NumberFormatException
System.out.println(i2);
Integer i3 = Integer.valueOf(98);
System.out.println(i3);
Integer i4 = Integer.valueOf("11");//如果此处字符串内也有英文也会报错NumberFormatException
System.out.println(i4);
}
}
public class IntegerDemo {
public static void main(String[] args) {
//int --- String
//方法1(简洁):因为字符串参与加法运算其实做的是连接,所以我们可以将空字符串和int变量进行相加
int number = 100;
String s1 = "" + number;
System.out.println(s1);
//方法2(专业):使用String的valueOf方法
String s2 = String.valueOf(number);
System.out.println(s1);
//String -- int
String s = "100";
//方法1:String -- Integer -- int,先使用Integer包装类的valueOf方法,再使用Integer的intValue方法
Integer i = Integer.valueOf(s);
int x = i.intValue();
System.out.println(x);
//方法2:直接使用Integer包装类的parseInt方法转换
int y = Integer.parseInt(s);
System.out.println(y);
}
}
public class IntegerDemo2 {
public static void main(String[] args) {
// (1)定义一个字符串。
String s = "91 27 46 38 50";
// (2)把字符串中的数字数据存储到一个int类型的数组中。
// 得到字符串中每一个数据:public String split(String regex)生成String数组。
String[] arr = s.split(" ");
// 定义一个int数组,把String[]数组中的每一个元素存储到int数组中:public static int parseInt(String s)。
int[] a = new int[arr.length];
for (int i = 0; i < arr.length; i++){
a[i] = Integer.parseInt(arr[i]);
}
// (3)对int数组进行排序。
Arrays.sort(a);
// (4)把顺序后的int数组中的元素进行拼接得到一个字符串,这里采用StringBuilder来实现。
StringBuilder sb = new StringBuilder();
for (int i = 0; i < a.length; i++){
sb.append(a[i]);
if (i != a.length - 1){
sb.append(" ");
}
}
String result = sb.toString();
// (5)输出结果。
System.out.println(result);
}
}
Integer i = 100;//自动装箱
i += 200;//i = i + 200; i + 200为自动拆箱,i = i + 200 为自动装箱
public static void main(String[] args) {
//装箱 - 把基本数据类型转换为对应的包装类型
//1.调用方法实现
Integer i = Integer.valueOf(100);
//2.自动装箱 - 将基本数据类型100直接赋值给引用类型ii,隐藏了调用valueOf方法的动作(JDK5之后)
Integer ii = 100;
//拆箱:把包装类型转换为对应的基本数据类型
//1.拆箱 - 比如我们要实现i += 200,按理来说我们就要先将i转换为int类型,再与200相加,最后通过自动装箱赋值回去给i
// 这里intValue()返回Integer对象的int值,这就叫做拆箱
i = i.intValue() + 200;//intValue()返回Integer对象的int值
//2.自动拆箱 - 隐藏了调用intValue()的动作
ii += 200;
System.out.println(i);//300
System.out.println(ii);//300
//一个小问题
Integer iii = null;
//报错NullPointerException,这里的iii为null,null自动拆箱时调用intValue(),
//所以报空指针异常,所以我们应该先进行判断iii!=null
//所以我们以后使用应用类型的时候,都要先进行判断
iii += 300;
}
基本数据类型 | 包装类 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
public static void main(String[] args) {
Integer a = new Integer(3);
Integer b = 3; //将3自动装箱成Integer类型
int c = 3;
System.out.println(a == b); //false,两个引用没有引用同一对象
System.out.println(a == c); //true,a自动拆箱成int类型再和c比较
}
public static void main(String[] args) {
Integer f1 = 100, f2 = 100, f3 = 150, f4 = 150;
System.out.println(f1 == f2);
System.out.println(f3 == f4);
}
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
其中IntegerCache为Integer的内部类,我们跟进。
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
简单地说,如果字面量的值在-128到127之间,那么不会new新的Integer对象,而是直接引用常量池中的Integer对象,所以上面的面试题中f1f2的结果是true,而f3f4的结果是false。
(1)注意我们学习的是java.util包下的Date类而不是java.sql包下的Date类(java.util包的Date类为java.sql包下Date类的父类)。另外注意导包的时候也选择java.util包的Date类。
(2)Date代表了一个特定的时间,精确到毫秒。
方法名 | 说明 |
---|---|
public Date() | 分配一个Date对象,并初始化,以便它代表它被分配的时间,精确到当前时间的毫秒值 |
public Date(long date) | 分配一个Date对象,并将其初始化为表示从标准基准时间起指定的毫秒数 |
public static void main(String[] args) {
//public Date():分配一个Date对象,并初始化,以便它代表它被分配的时间,精确到毫秒
Date d1 = new Date();
System.out.println(d1);//Sat Nov 20 11:05:13 CST 2021,这也说明Date类重写了toString方法
//public Date(long date):分配一个Date对象,并将其初始化为表示从标准基准时间起指定的毫秒数
long date = 1000 * 60 * 60;
Date d2 = new Date(date);
System.out.println(d2);//Thu Jan 01 09:00:00 CST 1970,注意这个时间是中国时区,CST为中国时区缩写
}
方法名 | 说明 |
---|---|
public long getTime() | 获取的是日期对象从1970年1月1日00:00:00到现在的毫秒值 |
public void setTime(long time) | 设置时间,给的是毫秒值 |
public static void main(String[] args) {
Date d = new Date();
//public long getTime():获取的是日期对象从1970年1月1日00:00:00到现在的毫秒值
System.out.println(d.getTime());//1637356610033
System.out.println(d.getTime() / 1000 / 60 / 60 / 24 / 365);//51
//public void setTime(long time):设置时间,给的是毫秒值
long time = System.currentTimeMillis();//currentTimeMillis()以毫秒为单位返回当前时间
d.setTime(time);
System.out.println(d);//Sat Nov 20 05:16:50 CST 2021
}
(1)我们在学习Date类的时候,创建一个日期对象,直接在控制台输出,看到的是不利于阅读的日期信息,我们更想看到年月日、时分秒这样很具体的信息,那要怎么实现呢?我们来看看SimpleDateFormat类。
(2)SimpleDateFormat是一个具体的类,用于以区域设置敏感的方式格式化(将日期转换为字符串)和解析(将字符串转换为日期)日期。我们重点学习日期格式化和解析。
(3)在SimpleDateFormat类中,日期和时间格式由日期和时间模式字符串指定,在这些字符串(日期和时间模式字符串)中,从’A’到’Z’以及从’a’到’z’引导的字母被解释为表示日期或时间字符串的组件的模式字母。(人话:通过使用日期模式字符串和时间模式字符串这两种字符串,将日期转换为一定的格式(即格式化)。这两种字符串中的’A’到’Z’以及从’a’到’z’,被称为这些字符串的组件的模式字母)
(4)常用的模式字母及对应关系如下:
模式字母 | 对应单位 |
---|---|
y | 年 |
M | 月 |
d | 日 |
H | 时 |
m | 分 |
s | 秒 |
方法名 | 说明 |
---|---|
public SimpleDateFormat() | 构造一个SimpleDateFormat,使用默认的模式和日期格式 |
public SimpleDateFormat(String pattern) | 构造一个SimpleDateFormat,使用给定的模式和默认的日期格式 |
public static void main(String[] args) throws ParseException {
//格式化:从Date到String
Date d = new Date();
//使用无参构造生成SimpleDateFormat对象,模式和日期格式为默认
SimpleDateFormat sdf1 = new SimpleDateFormat();
System.out.println(sdf1.format(d));//21-11-20 上午11:14
//使用给定的模式和默认的日期格式
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
System.out.println(sdf2.format(d));//2021年11月20日 11:14:06
//解析:从String到Date
String ss = "2048-11-11 11:11:11";
//使用parse方法将字符串解析为日期
SimpleDateFormat sdf3 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//注意这里的模式要解析的字符串对应,否则报错ParseException
Date dd = sdf3.parse(ss);
System.out.println(dd);
}
public class DateUtils {
//一般来说,工具类的构造方法设置为私有,成员方法设置为静态,禁止外界创建对象
private DateUtils(){};
public static String dateToString(Date date, String format){
SimpleDateFormat sdf = new SimpleDateFormat(format);
return sdf.format(date);
}
public static Date stringToDate(String d, String format) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat(format);
return sdf.parse(d);
}
}
public class DateDemo {
public static void main(String[] args) throws ParseException {
Date date = new Date();
String s = DateUtils.dateToString(date, "yyyy-MM-dd HH:mm:ss");
System.out.println(s);//2021-11-20 14:59:15
String s2 = DateUtils.dateToString(date,"yyyy年MM月dd日");
System.out.println(s2);
String s3 = DateUtils.dateToString(date,"HH:mm:ss");
System.out.println(s3);
String s4 = "2011-11-12 13:14:14";
Date date2 = DateUtils.stringToDate(s4,"yyyy-MM-dd HH:mm:ss");
System.out.println(date2);//Sat Nov 12 13:14:14 CST 2011
}
}
(1)Calendar 类是一个抽象类,它为特定瞬间与一组诸如 YEAR、MONTH、DAY_OF_MONTH、HOUR 等 日历字段之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法。
(2)Calendar 提供了一个类方法 getInstance,以获得此类型的一个通用的对象。Calendar 的 getInstance 方法返回一个 Calendar 对象,其日历字段已由当前日期和时间初始化:Calendar rightNow = Calendar.getInstance();
public static void main(String[] args) {
Calendar c = Calendar.getInstance();//通过查看getInstance方法,我们可以知道此方法生成的Calendar对象是通过多态实现的
System.out.println(c);//很长的一个字符串
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH) + 1;//加1是因为Calendar对象内月份从0开始计算
int date = c.get(Calendar.DATE);
System.out.println(year + "年" + month + "月" + date + "日");//2021年10月20日
}
方法 | 说明 |
---|---|
public int get(int field) | 返回给定日历字段的值 |
public abstract void add(int field, int amount) | 根据日历的规则,将指定的时间量field添加或者减去给定的日历字段amount |
public final void set(int year, int month, int date) | 设置当前日历的年月日 |
public static void main(String[] args) {
Calendar c = Calendar.getInstance();
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH) + 1;//加1是因为Calendar对象内月份从0开始计算
int date = c.get(Calendar.DATE);
System.out.println(year + "年" + month + "月" + date + "日");//2021年11月20日
//3年前的今天
c.add(Calendar.YEAR, -3);
year = c.get(Calendar.YEAR);
System.out.println(year + "年");//2018年
//10年后的5天前
c.add(Calendar.YEAR, 10);
c.add(Calendar.YEAR, -5);
year = c.get(Calendar.YEAR);
date = c.get(Calendar.DATE);
System.out.println(year + "年" + date + "日");//2023年20日
c.set(2018,9 + 1,3);
year = c.get(Calendar.YEAR);
month = c.get(Calendar.MONTH) - 1;
date = c.get(Calendar.DATE);
System.out.println(year + "年" + month + "月" + date + "日");//2018年9月3日
}
public class DaysOfFebruary {
public static void main(String[] args) {
Calendar c = Calendar.getInstance();
//(1)键盘录入任意的年份;
System.out.println("请输入您要查询的年份:");
Scanner sc = new Scanner(System.in);
int y = sc.nextInt();
//(2)设置日历对象的年(来自于键盘录入)、月(设置为3月,月份是从0开始的,所以设置的值是2)、日(设置为1日);
c.set(y, 2, 1);
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH) + 1;
int date = c.get(Calendar.DATE);
System.out.println(year + "年" + month + "月" + date + "日");//2020年3月1日
//(3)3月1日往前推一天,也就是2月的最后一天,获取这一天输出即可。
c.add(Calendar.DATE, -1);
System.out.println("该年份的二月一共有" + c.get(Calendar.DATE) + "天");//该年份的二月一共有29天
}
}