常用API概述:
基础知识学完了. 开启了一个新篇章。在前面, 我们几乎把Java的基础语法学完了。接下来, 我们要对JDK提供给我们的一些工具类进行详细的剖析,为了后面的项目开发继续打基础。
参考官方文档JDK中所有的API:https://docs.oracle.com/javase/8/docs/api/index.html
也可以下载一个中文jdk文档(有检索功能)
https://www.jb51.net/books/698419.html
在本章你能学到:
- 数学类Math, 除了加减乘除以外的其他数学运算都在这里了
包装类, 基本数据类型实际上并不属于对象的范畴, 所以java提供给了包装类把非面向对象的基本数据类型包装成java中的对象
基本数据类型: byte short int long float double char boolean
时间类Date 和 Calendar, 时间在程序里怎么表示, 以及时间差怎么计算
- 字符串, 前面咱们只是简单认识了一下字符串, 这里来具体的介绍数据类型的霸主, 字符串都有哪些操作
- StringBuffer和StringBuilder, 另类的两个字符串
- DecimailFormat 数字的格式化
一、数学类Math
数学操作,很多小伙伴会想到 + - * / % . 没错, 我们接触最多的也确实就这几个。但是有些时候啊,这些操作不够用,比如说我想让你帮我计算一下一元二次方程的解. 瞬间石化..
ax2+bx+c = 0 的解是:
来, 你用加减乘除来搞~~ 搞不定了吧. 哈哈.
此时我们就需要数学类的帮助来完成相应的操作了.
数学类提供的一些常用方法:
- pow(x,y) 计算x的y次幂
- abs(x). 计算x的绝对值
- log(x). 计算以e为底x的对数, e是啥, 我只能告诉你e被称为欧拉数….
- max(x,y) 返回x, y中大的那个数
- min(x, y) 返回x,y中小的那个数
- round(x) x四舍五入
- sqrt(x) 计算x的开平方,根号下x
- ceil(7.5) //返回大于或等于该浮点数的整数
- floor(3.6) //返回小于或等于该浮点数的整数
- random() //返回 [0.0,1.0)之间的浮点数
咱们就介绍这些 ,当然Math肯定不止这么多方法,对我们而言, 这些就足够用的了. 如果你需要看数学类的其他方法, 送你一个传送门:https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html
package com.xyq.math;public class Test {public static void main(String[] args) {System.out.println(Math.pow(3, 3)); // 3的3次方System.out.println(Math.abs(-12)); // 12System.out.println(Math.log(2)); // 以e为底, 2的对数System.out.println(Math.max(12, 33)); // 求大数 33System.out.println(Math.min(55, 33)); // 求小数 33System.out.println(Math.round(3.56789)); // 4 四舍五入System.out.println(Math.sqrt(3)); // 根号9 1.732}}
来吧, 解决一下一元二次方程吧
package com.xyq.math;import java.util.Scanner;public class Test {public static void main(String[] args) {Scanner sc = new Scanner(System.in);System.out.println("请输入a:");double a = sc.nextInt();System.out.println("请输入b:");double b = sc.nextInt();System.out.println("请输入c:");double c = sc.nextInt();// 先判断b*b-4*a*c是否大于0 . 不大于0无解double dt = b*b - 4*a*c;if (dt < 0){System.out.println("此方程无解");} else if(dt == 0){System.out.println("此方程有一个解");double x = -b/(2*a);System.out.println("x = " + x);} else {System.out.println("此方程有两个解");double x1 = (-b+Math.sqrt(dt)) / (2*a);double x2 = (-b-Math.sqrt(dt)) / (2*a);System.out.println("x1 = "+x1 + ", x2 = "+x2);}}}
二、基本数据类型的包装类
说包装类之前, 我们先看这样一段代码.
package com.xyq.pack;public class Test {public static void main(String[] args) {int a = 10;System.out.println(a.toString()); // 报错}}
为什么会报错呢? 想想啊, 前面我们说过, 任何类都要继承Object, 所以在java里认为万事万物皆为对象. 而toString()方法是Object提供的一个方法. 也就意味着, 所有的类都会有一个默认的toString(). 但是此时我们发现int类型不能执行这个toString(). 为什么呢? 因为!!!! int是基本数据类型, 根本就没有继承Object. 换句话说. 所有的基本数据类型都不在面向对象的范畴. 但是这又与Java纯面向对象编程语言相违背. 怎么办? Java很聪明. 既然int不是对象的范畴, 那我就想办法把你变成面向对象, 所以, java提供了基本数据类型的包装类来对基本数据类型进行包装. 包装之后的东西就是面向对象了.
基本数据类型包装类
| 基本类型 | 包装类型 |
|---|---|
| byte | Byte |
| short | Short |
| int | Integer |
| long | Long |
| float | Float |
| double | Double |
| char | Charactor |
| boolean | Boolean |
除了int和char以外都是基本数据类型首字母大写. 很好记.
那这些类有什么用
package com.xyq.pack;public class Test {public static void main(String[] args) {Integer t = new Integer(12); // new了个对象. 但是没什么实际意义. 和int i = 12 几乎是一样的.System.out.println(t); // 12Integer tt = new Integer(13);System.out.println(t+tt); // 数学运算也OK.}}
包装类最大的作用就是把基本数据类型变成了对象,实现不同类型之间转换
你看, 可以执行这么多方法了. 可能懵懂的你还是很不爽. 没用!!!! 好接下来就是重点了.
我们说, int并没有继承Object. 那就意味着. int不可以向上转型成Object. 对吧. 那如果我写一个方法接收Object类型的参数. int就不能给这个方法传参.
package com.xyq.pack;public class Test {public static void chi(Object obj){System.out.println(obj);}public static void main(String[] args) {chi(1); // 没报错}}
我们发现, 这段代码并没有报错. 讲道理应该报错才对啊. 这里就涉及到一个新的知识点, 自动打包和解包. 在java里, 基本数据类型是可以和包装类型进行无缝转换的.
Integer i = 1; // 自动打包成Integer对象int b = i; // 自动解包成int类型
所以, 在上面的代码里, 程序是自动把1转化成了Integer对象. 然后传给了obj. 中间有一个打包的过程.
怎么验证? 简单. 打印的时候打印obj.getClass()看看
package com.xyq.pack;public class Test {public static void chi(Object obj){System.out.println(obj.getClass()); // class java.lang.Integer}public static void main(String[] args) {chi(1); // 没报错}}
OK. 基本数据类型包装类存在的意义:
- 让基本数据类型有了面向对象的特征.
- 可以把字符串转化成各种基本数据类型
/*1.int转String*/int a = 100;String a1 = ""+a; //方式1String a2 = String.valueOf(a); //方式2/*2.String转int*/String b = "100";int b1 = Integer.parseInt(b);//方式1Integer b2 = Integer.valueOf(b); //方式2int b3 = b2.intValue();
规律: 字符串->基本数据类型
基本数据类型包装类.parse基本数据类型(待转化的内容)
- Integer.parseInt(“12”); //将字符串转化为整型
- Double.parseDouble();
- Long.parseLong();
- Boolean.parseBoolean();
案例:给定字符串”91 27 46 38 50” 按空格分割后排序输出
String s1 = "91 27 46 38 50";System.out.println(sortStr(s1));public static String sortStr(String s1){String[] strArr = s1.split(" ");StringBuilder sb = new StringBuilder();int[] arr = new int[strArr.length];for (int i = 0; i < arr.length; i++) {arr[i] = Integer.parseInt(strArr[i]);}Arrays.sort(arr);return Arrays.toString(arr);}
自动装箱和拆箱
- 装箱:把基本数据类型转换为对应的包装类类型
- 拆箱:把包装类类型转换为基本数据类型 ```java Integer a1 = Integer.valueOf(100); //装箱 Integer a2 = 100; //自动装箱,jdk5之后可以这么写,底层是上句代码
Integer a3 = Integer.valueOf(200); a3+=100; //自动拆箱,a3.intValue() +100
注意:在使用包装类的时候,如果做操作,最好先判断是否为null,推荐只要是对象 在使用前就必须进行部位null的判断<a name="RPIj5"></a>## 三、日期时间JDK文档:[https://docs.oracle.com/javase/8/docs/api/index.html](https:_docs.oracle.com_javase_8_docs_api_index)<br />`java.util.Date`, 日期类. 帮我们处理时间的一个类```javaimport java.util.Date;Date t1 = new Date();System.out.println(t1); //Tue Jun 16 09:02:27 CST 2020System.out.println(t1.getTime()); //时间撮 从1970年1月1日 0点0分0秒开始.System.out.println(t1.getYear()); //从1900年开始计算,该方法目前已弃用,IDEA会标记删除线System.out.println(t1.getMonth()+1); // 获取月份. 月份从0开始System.out.println(t1.getDate()); // 月内的第xxx天.System.out.println(t1.getHours()); // 小时System.out.println(t1.getMinutes()); // 分钟System.out.println(t1.getSeconds()); // 获取到秒
java.util.Calendar日历类:
Calendar rightNow = Calendar.getInstance();System.out.println(rightNow);//rightNow对象包含非常丰富的日期信息,比如WEEK_OF_YEAR=25 一年中的第25周,WEEK_OF_MONTH=3 一个月中的第3周;//java.util.GregorianCalendar[time=1592234532715,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=29,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2020,MONTH=5,WEEK_OF_YEAR=25,WEEK_OF_MONTH=3,DAY_OF_MONTH=15,DAY_OF_YEAR=167,DAY_OF_WEEK=2,DAY_OF_WEEK_IN_MONTH=3,AM_PM=1,HOUR=11,HOUR_OF_DAY=23,MINUTE=22,SECOND=12,MILLISECOND=715,ZONE_OFFSET=28800000,DST_OFFSET=0]
日历对象的常用的get方法:
System.out.println(rightNow.getTime()); // Calendar转化成DateSystem.out.println(rightNow.get(Calendar.YEAR)); // 年System.out.println(rightNow.get(Calendar.MONTH)+1); // 月 从0开始System.out.println(rightNow.get(Calendar.DAY_OF_MONTH)); // 日System.out.println(rightNow.get(Calendar.HOUR_OF_DAY)); // 小时, 24小时System.out.println(rightNow.get(Calendar.MINUTE)); // 分钟System.out.println(rightNow.get(Calendar.SECOND)); // 秒
日历对象的set方法:
// 在当前系统时间的基础上后延36小时rightNow.set(Calendar.HOUR_OF_DAY, rightNow.get(Calendar.HOUR_OF_DAY)+36);System.out.println(rightNow.get(Calendar.HOUR_OF_DAY)); // 小时, 24小时// 2月22日. 延后18天, 是几号?rightNow.set(Calendar.DAY_OF_MONTH, rightNow.get(Calendar.DAY_OF_MONTH)+18);String timefmt = ""+rightNow.get(Calendar.YEAR)+"年"+(rightNow.get(Calendar.MONTH)+1)+"月"+rightNow.get(Calendar.DAY_OF_MONTH)+"日 "+rightNow.get(Calendar.HOUR_OF_DAY)+"时"+rightNow.get(Calendar.MINUTE)+"分"+rightNow.get(Calendar.SECOND)+"秒";System.out.println(timefmt);
Date()对象格式化为标准时间:
Date t1 = new Date();System.out.println(t1); //Tue Jun 16 08:39:09 CST 2020// 创建一个格式化对象. 这里必须要通过构造方法传递一个日期格式. 说白了. 你想让日期显示成什么格式SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//将Date对象格式化为我们需要的日期时间格式String s = sdf.format(t1); // 格式化时间System.out.println(s); // 2020-06-16 08:39:09
将日期时间字符串格式化为时间对象
Scanner sc = new Scanner(System.in);System.out.println("请输入一个日期(yyyy-MM-dd): ");String s = sc.nextLine();SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");try {Date d = sdf.parse(s);// 转化 // 这里必须要手动处理异常. 原因: 用户输入的那玩意谁也保证不了. 所以很容易出问题. 必须异常处理System.out.println(d);} catch (ParseException e) {e.printStackTrace();}
注意:格式化sdf.parse()容易出错,必须要异常处理
练习:时间差计算
String s1 = "2018-01-01 12:00:00";String s2 = "2018-01-01 13:44:00";//首先把这两个字符串转化为Date对象SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");try {Date t1 = sdf.parse(s1);Date t2 = sdf.parse(s2);//获取毫秒long t1_millSec = t1.getTime();long t2_millSec = t2.getTime();//获取秒long t1_sec = t1_millSec/1000;long t2_sec = t2_millSec/1000;System.out.println(t1_sec);System.out.println(t2_sec);//获取总分钟long t1_min = t1_sec / 60;long t2_min = t2_sec / 60;//获取小时long t1_hour = t1_min/60;long t2_hour = t2_min/60;//获取分钟long t1_minute = t1_min % 60; //0long t2_minute = t2_min % 60; //44System.out.println("您上网的时间差为:"+Math.abs(t1_hour-t2_hour)+"小时"+Math.abs(t1_minute-t2_minute)+"分钟;");} catch (ParseException e) {e.printStackTrace();}
四、字符串详解
1.字符串的扩展用法
字符串是程序中使用频率最高的一种数据类型,Java的JDK提供了非常多的使用方法
首先来看看两种创建字符串的方式:
String s1 = "胡辣汤";String s2 = new String("狗不理");

这两种方式在内存中创建的方式不同,但是在我们使用上, 是没有什么区别和影响的。
接下来, 看看有哪些操作吧:
package com.xyq.str;public class TestString {public static void main(String[] args) {String s = "今天特别想吃哈密瓜";//charAt(int) 获取到字符串中某个位置的字符. 从0开始数System.out.println(s.charAt(0)); // 今System.out.println(s.charAt(4)); // 想// concat(String) 字符串拼接. 和+是一样的System.out.println(s.concat("伊丽莎白")); // 今天特别想吃哈密瓜伊丽莎白//今天特别想吃哈密瓜 深坑: 字符串是不可变的. 不论做什么操作, 原来的字符串不会发生改变, 每次操作都是返回一个新字符串System.out.println(s);// contains(String) 判断字符串中是否包含xxxSystem.out.println(s.contains("明天")); // falseSystem.out.println(s.contains("哈密瓜")); // true// startswith(String) 判断字符串是否以xxxx开头// endswith(String) 判断字符串是否以xxxx结尾System.out.println(s.startsWith("今天")); // trueSystem.out.println(s.endsWith("哈密瓜")); // true// equals(String) 判断两个字符串内容是否一致// equalsIgnoreCase(String) 判断两个字符串内容是否一致(忽略大小写)System.out.println("abc".equals("abc")); // trueSystem.out.println("abc".equalsIgnoreCase("ABC")); // true// indexOf(String) 根据给定的字符串计算该字符串首次出现的位置 -> 从前向后// lastIndexOf(String) 根据给定的字符串计算该字符串最后出现的位置-> 从后向前System.out.println(s.indexOf("特别")); // 2System.out.println(s.lastIndexOf("哈密瓜")); // 6// isEmpty() 判断字符串是否是空字符串System.out.println("".isEmpty()); // trueSystem.out.println(" ".isEmpty()); // false// length() 字符串的长度 -> 有多少个字符组成(区别数组长度 arr.length)System.out.println(s.length()); // 9// replace(String, String) 把xxx替换成xxxString s1 = s.replace("今天", "昨天");System.out.println(s); // 今天特别想吃哈密瓜 没变~~~~ 字符串不可变哦System.out.println(s1); // 昨天特别想吃哈密瓜 获得的新字符串// replaceFirst(String, String); 替换第一个String s2 = s.replace("天", "日");System.out.println(s2); // 今日特别想吃哈密瓜// split(String regex) 字符串切割,返回字符串数组String[] strs = s.split("想吃"); // 使用"想吃"进行字符串切割. 切割的结果放在字符串数组中System.out.println(strs[0]); // 今天特别System.out.println(strs[1]); // 哈密瓜// split(String regex, int limit) 分成3份String arr[] = "a_b_c_d_e".split("_",3);for (String item:arr) {System.out.println(item); //a b c_d_e}// subString(int beginIndex, int endIndex) 字符串截取. 从xxx截取到xxx//如果不给endIndex 就从beginIndex 截取到字符串结尾String s3 = s.substring(2, 4);System.out.println(s3); // 特别// toUpperCase(); 转化成大写// toLowerCase(); 转化成小写String s4 = "abcDefGhIJKLMN";System.out.println(s4.toUpperCase());System.out.println(s4.toLowerCase());// trim(); 去掉左右两端的空格String s5 = " 哇哈哈哈哈 ";System.out.println(s5.trim()); //哇哈哈哈哈//hashCode() 返回该字符串的哈希值System.out.println("xiong".hashCode()); //114060759System.out.println("zhao".hashCode()); //3737564}}
总结:
字符串是不可变的。不论做什么操作, 原来的字符串不会发生改变, 每次操作都是返回一个新字符串;
.compareTo() 方法
A.compareTo(B) //比较A B
返回值
返回值是整型,它是先比较对应字符的大小(ASCII码顺序),如果第一个字符和参数的第一个字符不等,结束比较,返回他们之间的差值,如果第一个字符和参数的第一个字符相等,则以第二个字符和参数的第二个字符做比较,以此类推,直至比较的字符或被比较的字符有一方结束。如果参数字符串等于此字符串,则返回值 0;
- 如果此字符串小于字符串参数,则返回一个小于 0 的值;
如果此字符串大于字符串参数,则返回一个大于 0 的值。
String str1 = "Strings";String str2 = "Strings";String str3 = "Strings123";int result = str1.compareTo( str2 );System.out.println(result); //0result = str2.compareTo( str3 );System.out.println(result); //-3result = str3.compareTo( str1 );System.out.println(result); //3
2.StringBuffer和StringBuilder
在前面的学习中我们了解到字符串是一个不可变的数据类型。也就是说一旦字符串被创建好, 就不可以被修改。并且每次操作都会返回一个新的字符串,如果反复的对字符串进行操作,此时势必会造成大量的内存浪费。
比如:“我的妈呀”+”你的妈呀”+”谁的妈呀”+”怎么这么卡”,在老的JDK中 每次相加都会产生一个新的字符串, 非常的浪费内存资源, 但是在新版本中, JDK对这里进行了优化。每次 + 都是执行用的StringBuilder中的字符串拼接方法。为什么呢? 因为StringBuilder是可以改变的字符串,都在原来的基础上进行操作。所以不会产生内存浪费,接下来我们来看看这个叫StringBuilder的东西。
StringBuilder: 可变的字符串
用法:package com.xyq.str;public class TestStringBuilder {public static void main(String[] args) {StringBuilder sb = new StringBuilder(); // 空的字符串.StringBuilder sb2 = new StringBuilder("王二麻子的麻子特别特别麻"); // 也可以给出具体的字符串. 都OKsb2.append(", 李二麻子的麻子就不是特别麻"); // 在后面追加System.out.println(sb2); // 王二麻子的麻子特别特别麻, 李二麻子的麻子就不是特别麻//还可以追加整数sb2.append(123); //可以追加任何数据类型//在指定位置插入sb2.insert(3, "插入");// 还可以在中间插入System.out.println(sb2); // 王二麻插入子的麻子特别特别麻, 李二麻子的麻子就不是特别麻123String s = sb2.toString(); // 转化回正常的普通字符串System.out.println(s);}}
关于StringBuilder, 咱们就说这么多. 足够大家在平时使用了
StringBuffer和StringBuilder基本上一模一样,区别是StringBuffer线程安全,StringBuilder线程不安全。
等到后面我们学到线程的时候, 在给大家说他俩的区别,就目前而言. 你可以认为没区别。五、DecimalFormat小数格式化
DecimalFormat顾名思义, 就是用来格式化数字的,这东西有什么用? 想想10/3.0 得到那种无限循环小数,现实生活中价格都要保留小数点后两位怎么办??? 就可以通过DecimalFormat对小数进行格式化处理。
package com.xyq.num;import java.text.DecimalFormat;public class TestNumberFormat {public static void main(String[] args) {double d = 9/2.0;System.out.println(d);DecimalFormat df = new DecimalFormat(".00"); // 保留小数点后两位String s = df.format(d);System.out.println(s); // 4.50DecimalFormat df2 = new DecimalFormat(".##"); // 保留小数点后两位String s2 = df.format(d);System.out.println(s2); // 4.50}}
格式:

这一堆格式中, 我们程序员要用的就三个:
0 : 数字
# : 数字
. : 小数点.00 和 .## 是一样的,都是保留两位小数
用法案例
判断某个人是不是姓张
Scanner sc = new Scanner(System.in);System.out.println("请输入一个人的名字:");String name = sc.nextLine();System.out.println(name.startsWith("张")?"是的":"不是"); //三元表达式
打印字符串中每一个字符
String s = "I love you";for(int i = 0; i < s.length(); i++){System.out.println(s.charAt(i));}//当然还可以用for each方法
有如下学生信息, 请计算并打印出每个学生的平均分
String[] stus = {"小绿_数学_12_语文_33_英语_42", "钢管男_数学_25_语文_56_英语_27","泰斯波尔_数学_99_语文_88_英语_120"};for(int i =0; i < stus.length; i++){String stu = stus[i]; // 获取到每个学生的信息// 把学生信息进行切割得到数组 {"小绿","数学","12","语文","33","英语","42"}String[] stuInfo = stu.split("_");String name = stuInfo[0];String math = stuInfo[2];String chinese = stuInfo[4];String english = stuInfo[6];// 字符串转化成数字 Integer.parseInt()int total = Integer.parseInt(math)+Integer.parseInt(chinese)+Integer.parseInt(english);double avg = total / 3.0;System.out.println(name+"平均分: "+avg);}
让用户输入一个数学表达式: 3+6+9+18 , 编程完成数学表达式的计算
package com.xyq.homework;import java.util.Scanner;public class Test1 {public static void main(String[] args) {Scanner sc = new Scanner(System.in);System.out.println("请输入一个加法表达式:");String content = sc.nextLine(); // 3+6+9+12// 去除字符串中所有空格," xiong ".trim() 去除字符串左右两端空格content = content.replace(" ", "");// 切割// + 是正则表达式的一个元字符. 此时想要用+切割. 这里必须要写\\+, 关于正则, 后面会专门找一章来给大家讲解.String[] strs = content.split("\\+");for(int i = 0; i < strs.length; i++){System.out.println(strs[i]);}}}
计算手速
效果:
准备测试. 请狂按enter你按了你按了你按了你按了你按了你按了你按了你按了你按了你按了// 20秒后// 您的手速是: 30.28次/秒
编程实现:
package com.xyq.homework;import java.text.DecimalFormat;import java.util.Calendar;import java.util.Date;import java.util.Scanner;public class Test2 {public static void main(String[] args) {Scanner sc = new Scanner(System.in);System.out.println("游戏随时可以开始, 按enter开始");sc.nextLine(); // 程序停在这里,直到用户按下Enter键int count = 0;//计算出结束游戏的时间Calendar cal = Calendar.getInstance();cal.set(Calendar.SECOND, cal.get(Calendar.SECOND)+20); // 向后算20秒Date end = cal.getTime();long endlong = end.getTime(); //时间撮while(endlong - new Date().getTime()>=0){ // 时间差是0. 结束游戏sc.nextLine();System.out.println(count);count++; // 按了一次}double rate = count / 20.0; // 计算频率DecimalFormat df = new DecimalFormat(".00"); // 格式化数字System.out.println("一共按了"+count+"次, 您的手速是:" + df.format(rate)+"/秒");}}
六、Object类
| 变量和类型 | 方法 | 描述 |
|---|---|---|
protected [Object](Object.html) |
[clone](#clone())() |
创建并返回此对象的副本。 |
boolean |
[equals](#equals(java.lang.Object))([Object](Object.html) obj) |
指示某个其他对象是否“等于”此对象。 |
[类](Class.html)<?> |
[getClass](#getClass())() |
返回此 Object的运行时类。实际上就是当前运行的.java程序的包名+类名 如com.xjt.duo_tai.Dog |
int |
[hashCode](#hashCode())() |
返回对象的哈希码值。 |
void |
[notify](#notify())() |
唤醒正在此对象监视器上等待的单个线程。 |
void |
[notifyAll](#notifyAll())() |
唤醒等待此对象监视器的所有线程。 |
[String](String.html) |
[toString](#toString())() |
返回对象的字符串表示形式。 |
void |
[wait](#wait())() |
导致当前线程等待它被唤醒,通常是 通知或 中断 。 |
void |
[wait](#wait(long))(long timeoutMillis) |
导致当前线程等待它被唤醒,通常是 通知或 中断 ,或者直到经过一定量的实时。 |
void |
[wait](#wait(long,int))(long timeoutMillis, int nanos) |
导致当前线程等待它被唤醒,通常是 通知或 中断 ,或者直到经过一定量的实时。 |
toString()
读源码,光标选中该方法按下Ctrl+B
Animal a1 = new Dog();System.out.println(a1); //com.xjt.duo_tai.Dog@2f4d3709//查看System.out.println(a1);源码流程/*1.public void println(String x) {if (getClass() == PrintStream.class) {writeln(String.valueOf(x));} else {synchronized (this) {print(x);newLine();}}}*//*2.public static String valueOf(Object obj) {return (obj == null) ? "null" : obj.toString();}*//*3.getClass().getName() 返回com.xjt.duo_tai.Dog 包名全路径public String toString() {return getClass().getName() + "@" + Integer.toHexString(hashCode());}*/
通过IDEA编辑器重写Animal类的toString方法
@Overridepublic String toString() {return "Animal{" +"name='" + name + '\'' +", age=" + age +'}';}
equals()
Animal a1 = new Dog("汪汪叫","小白");Animal a2 = new Dog("汪汪叫","小白");System.out.println(a1 == a2); //falseSystem.out.println(a1.equals(a2)); //false//源码中equals() 比较的是两个对象的地址public boolean equals(Object obj) {return (this == obj);}
七、Arrays
首先自己手写一个冒泡排序
public static String bubble(int[] arr){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]){int temp = arr[j];arr[j] = arr[j+1];arr[j+1] = temp;}}}StringBuilder sb = new StringBuilder("[");for (int item:arr) {sb.append(item).append(",");}sb.deleteCharAt(sb.length()-1).append("]");return sb.toString();}
因为排序算法非常常用,因此Arrays类给我们提供了,请看下面Arrays类的常用方法:
| 方法名 | 描述 |
|---|---|
| public static void sort(int[] arr) | 将指定的数组按升序排序。 |
| public static String toString(int[] arr) | 返回指定数组内容的字符串表示形式 |
int[] arr = {12, 56, 3, 41, 68, 20, 6, 8, 5, 10};Arrays.sort(arr);System.out.println(Arrays.toString(arr)); //[3, 5, 6, 8, 10, 12, 20, 41, 56, 68]
import java.util.Arrays
@工具类的设计思想:
- 构造方法用private修饰(外界无法实例化,通过类名调用方法)
- 成员用public static修饰,可直接用
类名.方法调用八、日期时间类
Date类
java.util.Date构造方法
| 构造器 | 描述 | | —- | —- | |[Date](#%3Cinit%3E())()| 分配Date对象并对其进行初始化,使其表示分配时间,测量Date到毫秒。 | |[Date](#%3Cinit%3E(long))(long date)| 分配Date对象并初始化它以表示自标准基准时间(称为“纪元”)以来的指定毫秒数,即1970年1月1日00:00:00 GMT。 |
方法
| 方法 | 描述 |
|---|---|
public long getTime() |
返回自此 Date对象表示的1970年1月1日00:00:00 GMT以来的毫秒数。 |
| public void setTime(long time) |
将此 Date对象设置为表示格林威治标准时间1970年1月1日00:00:00之后的 time毫秒的时间点。 |
示例:
Date dt = new Date();long time = dt.getTime();System.out.println(time); //1604413154803 毫秒long tm = 1*1000*60*60;Date dt2 = new Date();dt2.setTime(tm);System.out.println(dt2); //Thu Jan 01 09:00:00 CST 1970//CST中国标准时间,东八区与格林尼治时间相差8小时
SimpleDateFormat
构造方法
| 构造器 | 描述 |
|---|---|
[SimpleDateFormat](#%3Cinit%3E())() |
构造一个 SimpleDateFormat使用默认模式和日期格式符号默认 FORMAT区域设置。 |
[SimpleDateFormat](#%3Cinit%3E(java.lang.String))([String](../lang/String.html) pattern) |
构造一个 SimpleDateFormat使用给定的模式和默认的默认日期格式符号 FORMAT区域设置。 |
[SimpleDateFormat](#%3Cinit%3E(java.lang.String,java.text.DateFormatSymbols))([String](../lang/String.html) pattern, [DateFormatSymbols](DateFormatSymbols.html) formatSymbols) |
使用给定的模式和日期格式符号构造 SimpleDateFormat 。 |
[SimpleDateFormat](#%3Cinit%3E(java.lang.String,java.util.Locale))([String](../lang/String.html) pattern, [Locale](../util/Locale.html) locale) |
使用给定模式和给定语言环境的默认日期格式符号构造 SimpleDateFormat 。 |
方法
| 方法 | 描述 |
|---|---|
| public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition pos) | 将给定的 Date为日期/时间字符串,并将结果附加到给定的 StringBuffer |
| @Deprecated public static long parse(String s) | 尝试将字符串s解释为日期和时间的表示 |
示例:
Date d1 = new Date();SimpleDateFormat sdf = new SimpleDateFormat();String t1 = sdf.format(d1);System.out.println(t1); //2020/11/3 下午10:42SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String t2 = sdf2.format(d1);System.out.println(t2); //2020-11-03 22:42:42Date dt = sdf2.parse("2020-11-03 22:42:42");System.out.println(dt); //Tue Nov 03 22:42:42 CST 2020
案例:日期工具类
说明:类名.stringToDate(Date,format) 将日期Date对象转化为格式化时间字符串类名.dateToString(String,format) 将格式化时间字符串转化为日期Date对象
注意:工具类的设计思想,可参考上文
public class DateUtils {private DateUtils() {}public static String dateToString(Date dt, String format){SimpleDateFormat sdf = new SimpleDateFormat(format);String fmt = sdf.format(dt);return fmt;}public static Date stringToDate(String time,String format) throws ParseException {SimpleDateFormat sdf = new SimpleDateFormat(format);Date tt = sdf.parse(time);return tt;}}//测试Date date = new Date();String s1 = DateUtils.dateToString(date, "yyyy-MM-dd HH:mm:ss");System.out.println(s1); //2020-11-04 09:41:21String s2 = DateUtils.dateToString(date, "yyyy年MM月dd日");System.out.println(s2); //2020年11月04日String s3 = DateUtils.dateToString(date, "HH:mm:ss");System.out.println(s3); //09:41:21String tm = "2020-11-11 12:10:52";Date date1 = DateUtils.stringToDate(tm, "yyyy-MM-dd HH:mm:ss");System.out.println(date1); //Wed Nov 11 12:10:52 CST 2020
Calendar日历类
静态字段
| 字段声明 | 字段 | 描述 |
|---|---|---|
| public static final int YEAR | YEAR | 年份 |
| public static final int MONTH | MONTH | 月份 |
| public static final int DATE public static final int DAY_OF_MONTH |
DATE DAY_OF_MONTH |
日 |
| public static final int WEEK_OF_YEAR | WEEK_OF_YEAR | 当年的第几周 |
| public static final int WEEK_OF_MONTH | WEEK_OF_MONTH | 当年的第几个月 |
| public static final int DAY_OF_YEAR | DAY_OF_YEAR | 当年的第几天 |
| public static final int DAY_OF_WEEK | DAY_OF_WEEK | 一周中的第几天 |
| public static final int DAY_OF_WEEK_IN_MONTH | DAY_OF_WEEK_IN_MONTH | 一个月中第几周 |
| public static final int HOUR public static final int HOUR_OF_DAY |
HOUR HOUR_OF_DAY |
小时(12小时制) 小时(24小时制) |
| public static final int MINUTE | MINUTE | 分钟 |
| public static final int SECOND | SECOND | 秒 |
构造方法
Calendar instance = Calendar.getInstance();
方法
| 方法声明 | 描述 | 示例 |
|---|---|---|
| public int get(int field) | 返回给定日历字段的值 | Calendar instance = Calendar.getInstance(); int year = instance.get(Calendar.YEAR); int month = instance.get(Calendar.MONTH)+1; int day_of_month = instance.get(Calendar.DAY_OF_MONTH); int date = instance.get(Calendar.DATE); int hour = instance.get(Calendar.HOUR); int minute = instance.get(Calendar.MINUTE); int second = instance.get(Calendar.SECOND); |
| public abstract void add(int field, int amount) | 根据日历的规则,将指定的时间量添加或减去给定的日历字段 | //需求1:5年前的今天instance.add(Calendar.YEAR,-5);//需求2:3年后的10天前// instance.add(Calendar.YEAR,3); |
| public final void set(int year, int month, int date) | 设置日历字段的值(年月日) | instance.set(2020,11,11); |
示例:
Calendar instance = Calendar.getInstance();// Date time = instance.getTime();// System.out.println(time); //Wed Nov 04 10:13:48 CST 2020//// int year = instance.get(Calendar.YEAR);// int month = instance.get(Calendar.MONTH)+1;// int day_of_month = instance.get(Calendar.DAY_OF_MONTH);// int date = instance.get(Calendar.DATE);// System.out.println(year+"年"+month+"月"+day_of_month+"日");// System.out.println(date);//需求1:3年前的今天// instance.add(Calendar.YEAR,-3);// int year = instance.get(Calendar.YEAR);// int month = instance.get(Calendar.MONTH)+1;// int day_of_month = instance.get(Calendar.DAY_OF_MONTH);// System.out.println(year+"年"+month+"月"+day_of_month+"日");//需求2:2年后的10天前// instance.add(Calendar.YEAR,2);// instance.add(Calendar.DATE,-10);// int year = instance.get(Calendar.YEAR);// int month = instance.get(Calendar.MONTH)+1;// int day_of_month = instance.get(Calendar.DAY_OF_MONTH);// System.out.println(year+"年"+month+"月"+day_of_month+"日");// int hour = instance.get(Calendar.HOUR);// int minute = instance.get(Calendar.MINUTE);// int second = instance.get(Calendar.SECOND);// System.out.println(hour+","+minute+","+second);
案例:
instance.set(2020,2,1);instance.add(Calendar.DATE,-1);System.out.println(instance);/** java.util.GregorianCalendar[time=1582944375527,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",* offset=28800000,dstSavings=0,useDaylight=false,transitions=31,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2020,MONTH=1,WEEK_OF_YEAR=9,* WEEK_OF_MONTH=5,DAY_OF_MONTH=29,DAY_OF_YEAR=60,DAY_OF_WEEK=7,DAY_OF_WEEK_IN_MONTH=5,AM_PM=0,HOUR=10,HOUR_OF_DAY=10,MINUTE=46,SECOND=15,MILLISECOND=527,ZONE_OFFSET=28800000,DST_OFFSET=0]* */int day = instance.get(Calendar.DATE);System.out.println(day); //29
