外围概述:本篇咱们将会学习罕用的API,其中有Object类、日期相干操作类、数组相干操作类Arrays、正则表达式;同时也会学习对于数组的一些罕用算法,其余中有冒泡排序、二分查找法。
第一章:Object类
1.1-概述(理解)
java.lang.Object
类是Java语言中的根类,每个类都应用 Object
作为超类。所有对象(包含数组)都实现这个类的办法。
如果一个类没有特地指定父类, 那么默认则继承自Object类。例如:
public class MyClass /*extends Object*/ { // ...}
1.2-本地办法(理解)
在Object类的源码中定义了native
润饰的办法,native
润饰的办法称为本地办法。
本地办法的特点:
- 被native润饰的办法,非Java语言编写,是由C++语言编写。
- 本地办法在运行期间进入本地办法栈内存,本地办法栈是一块独立内存的区域。
- 本地办法的意义是和操作系统进行交互。
如Object类中局部源码:
private static native void registerNatives();static { registerNatives();}
当程序运行的时候,Object类会最先被加载到内存中。类进入内存后首先加载本人的动态成员,static代码块中调用了本地办法registerNatives()
,和操作系统进行交互。
查看Object类源码:在IDEA编辑器中,新建一个类,在类中一个main办法中new Object()
,鼠标停留在Object
类上,按住ctrl
+ 点击鼠标,进入Object类源码中。
1.3-toString办法(了解)
意识toString办法
办法申明:public String toString()
:返回该对象的字符串示意。
Object类toString()办法源码:
public String toString() { return getClass().getName() + "@" + Integer.toHexString(hashCode());}
源码剖析:
getClass().getName()
返回类的全限定名字。hashCode()
办法返回int值,能够临时了解为对象的内存地址。Integer.toHexString()
将int类型的值转成十六进制。- 因而调用对象的toString()办法将看到内存的地址值。
创立Person类,并调用办法toString()
public static void main(String[] args){ Student stu = new Student(); String str = stu.toString(); System.out.println(str); // www.penglei666.com.demo01.Student@5f2050f6 System.out.println(stu); // www.penglei666.com.demo01.Student@5f2050f6}
通过程序运行,失去论断,在输入语句中打印对象,就是在调用对象的toString()办法。
重写toString办法
因为toString办法返回的后果是内存地址,而在开发中,内存地址并没有理论的利用价值,常常须要依照对象的属性失去相应的字符串表现形式,因而也须要重写它。
public class Student { private String name; private int age; @Override public String toString() { return "Student:" + name + "," + age; } // 省略结构器与Getter Setter}
1.4-equals办法(了解)
意识equals办法
办法申明:public boolean equals(Object obj)
:批示其余某个对象是否与此对象“相等”。
Object类equals()办法源码:
public boolean equals(Object obj) { return (this == obj);}
源码剖析:
- this是以后对象,哪个对象调用的equals办法就示意哪个对象。
- obj表述传递的参数,参数类型Object,能够传递任意类型对象。
- this==obj 比拟两个对象的内存地址是否雷同
equals办法默认比拟两个对象的内存地址是否雷同,雷同则返回true。
重写equals办法
理论利用中,比拟内存地址是否雷同并没有意义,咱们能够定义对象本人的比拟形式,比拟对象中成员变量的值是否雷同。须要对办法进行重写。
需要:重写equals()办法,比拟两个对象中姓名和年龄是否雷同,如果姓名和年龄都雷同返回true,否则返回false。
public class Person { private String name; private int age; public boolean equals(Object obj){ //判断两个对象地址弱雷同,即为同一个对象 if(this == obj) return true; //obj对象为空,无需比拟,返回false if(obj == null) return false; //obj如果是Person类型对象,则强制转换 if(obj instanceof Person){ Person person = (Person)obj; //比拟两个对象的name属性和age属性,如果相等,返回true return this.name.equals(person.name) && this.age == person.age; } return false; }}
第二章:日期操作类
2.1-Date类(记忆)
构造方法
public Date()
:从运行程序的此时此刻到工夫原点经验的毫秒值,转换成Date对象,调配Date对象并初始化此对象,以示意调配它的工夫(准确到毫秒)。public Date(long date)
:将指定参数的毫秒值date,转换成Date对象,调配Date对象并初始化此对象,以示意自从规范基准工夫(称为“历元(epoch)”,即1970年1月1日00:00:00 GMT)以来的指定毫秒数。
public class Test01 { public static void main(String[] args) { Date date = new Date(); System.out.println(date); // Fri Jul 31 11:59:20 CST 2020 Date date2 = new Date(0); System.out.println(date2); // Thu Jan 01 08:00:00 CST 1970 }}
罕用办法
public long getTime()
把日期对象转换成对应的工夫毫秒值。public void setTime(long time)
把办法参数给定的毫秒值设置给日期对象。
public class Test02 { public static void main(String[] args) { Date date = new Date(); System.out.println(date.getTime()); // 1596168137169 date.setTime(15961681371611L); System.out.println(date); // Tue Oct 22 00:22:51 CST 2475 }}
毫秒值(工夫戳)和日期对象相互转换
日期对象转换为毫秒值:日期对象.getTime()
;
毫秒值转换为日期对象:new Date(long time)
;
获取以后工夫的毫秒值:System.currentTimeMillis()
public class Test02 { public static void main(String[] args) { // 从1970年到当初的总毫秒值(也叫工夫戳) long millis = System.currentTimeMillis(); System.out.println(millis); // 1596168719242 // 毫秒值转日期对象 Date date = new Date(millis); System.out.println(date); // Fri Jul 31 12:11:59 CST 2020 // 日期对象转毫秒值 long millis2 = date.getTime(); System.out.println(millis2); // 1596168719242 }}
2.2-DateFormat类(记忆)
概述
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文档。
转换方法
String format(Date date)
传递日期对象,返回格式化后的字符串。Date parse(String str)
传递字符串,返回日期对象。
public static void main(String[] args) throws ParseException { // 创立以后日期对象 Date date = new Date(); // 创立格式化对象 DateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); String dateStr = format.format(date); System.out.println(dateStr); // 2019-12-07 05:37:53 // 把格式化日期转换为日期对象 Date date2 = format.parse("2100-12-12 12:12:12"); System.out.println(date2); // Sun Dec 12 00:12:12 CST 2100 }
2.3-Calendar类(记忆)
概述
java.util.Calendar
是日历类,在Date后呈现,替换掉了许多Date的办法。该类将所有可能用到的工夫信息封装为动态成员变量,不便获取。日历类就是不便获取各个工夫属性的。
获取日历对象
Calendar是抽象类,不能创建对象,须要应用子类对象。java.util.GregorianCalendar
类是Calendar的子类,然而创立日历对象须要依据本地的时区,语言环境来创立,比拟艰难,Calendar类提供了静态方法 getInstance()间接获取子类的对象。
public static Calendar getInstance()
:应用默认时区和语言环境取得一个日历。
public static void main(String[] args) { // 获取日历对象 Calendar calendar = Calendar.getInstance(); }
罕用办法
罕用办法
public int get(int field)
:返回给定日历字段的值。public void set(int field, int value)
:将给定的日历字段设置为给定值。public abstract void add(int field, int amount)
:依据日历的规定,为给定的日历字段增加或减去指定的工夫量。public Date getTime()
:返回一个示意此Calendar工夫值(从历元到当初的毫秒偏移量)的Date对象。
field:Calendar类中提供很多成员常量,代表给定的日历字段:
字段值 | 含意 |
---|---|
YEAR | 年 |
MONTH | 月(从0开始,能够+1应用) |
DAY_OF_MONTH | 月中的天(几号) |
HOUR | 时(12小时制) |
HOUR_OF_DAY | 时(24小时制) |
MINUTE | 分 |
SECOND | 秒 |
DAY_OF_WEEK | 周中的天(周几,周日为1,能够-1应用) |
代码:
public static void main(String[] args) { // 获取日历对象 Calendar calendar = Calendar.getInstance(); // 获取以后日期的局部数据 System.out.println(calendar.get(Calendar.YEAR)); System.out.println(calendar.get(Calendar.MONTH)); // 月份 0-11 System.out.println(calendar.get(Calendar.DAY_OF_MONTH)); System.out.println(calendar.get(Calendar.HOUR_OF_DAY)); System.out.println(calendar.get(Calendar.MINUTE)); System.out.println(calendar.get(Calendar.SECOND)); System.out.println(calendar.get(Calendar.DAY_OF_WEEK)); }
练习
需要:获取任意一年的二月有多少天
剖析:
- 能够将日历设置到任意年的三月一日
- 向前偏移一天
- 获取偏移后的日历即可
代码:
public static void main(String[] args) { //键盘录入任意的年份 Scanner sc = new Scanner(System.in); System.out.println("请输出年:"); int year = sc.nextInt(); //设置日历对象的年、月、日 Calendar c = Calendar.getInstance(); c.set(year, 2, 1); //3月1日往前推一天,就是2月的最初一天 c.add(Calendar.DATE, -1); //获取这一天输入即可 int date = c.get(Calendar.DATE); System.out.println(year + "年的2月份有" + date + "天");
第三章:System类
3.1-概述(理解)
java.lang.System
类中提供了大量的静态方法,能够获取与零碎相干的信息或零碎级操作。System类公有润饰构造方法,不能创建对象,间接类名调用。
3.2-罕用办法(记忆)
3.3-测试程序运行时长(练习)
需要:在控制台输入1-10000,计算这段代码执行了多少毫秒
public static void main(String[] args) { //获取以后工夫毫秒值 System.out.println(System.currentTimeMillis()); // 计算程序运行工夫 long start = System.currentTimeMillis(); for (int i = 1; i <= 10000; i++) { System.out.println(i); } long end = System.currentTimeMillis(); System.out.println("共耗时毫秒:" + (end - start)); }
3.4-arryCopy办法(记忆)
参数
- Object src:要复制的数据源数组
- int srcPost:数据源数组的开始索引
- Object dest:复制后的目标数组
- int destPos:目标数组开始索引
- int length:要复制的数组元素的个数
代码
将源数组中从1索引开始,复制3个元素到目标数组中
public static void main(String[] args){ int[] src = {1,2,3,4,5}; int[] dest = {6,7,8,9,0}; //将源数组中从1索引开始,复制3个元素到目标数组中 System.arraycopy(src,1,dest,0,3); for(int i = 0 ; i < dest.length;i++){ System.out.println(dest[i]);}
3.5-gc办法(理解)
运行垃圾回收器,JVM将从堆内存中清理对象,清理对象的同时会调用对象的finalize()办法,JVM的垃圾回收器是通过另一个线程开启的,因而程序中的成果并不显著。
Person类
public class Person { protected void finalize() throws Throwable { System.out.println("对象被回收");}
测试类:
public static void main(String[] args){ new Person(); new Person(); new Person(); new Person(); new Person(); new Person(); System.gc();}
第四章:数组的冒泡排序
数组的排序,是将数组中的元素依照大小进行排序,默认都是以升序的模式进行排序,数组排序的办法很多,咱们解说的是数组的冒泡排序。
排序,都要进行数组 元素大小的比拟,再进行地位的替换。冒泡排序法是采纳数组中相邻元素进行比拟换位。
4.1-什么是冒泡排序(理解)
冒泡排序(Bubble Sort),是一种较简略的排序算法。
它反复地走访过要排序的元素列,顺次比拟两个相邻的元素,如果程序谬误就把他们替换过去。走访元素的工作是反复地进行直到没有相邻元素须要替换,也就是说该元素列曾经排序实现。
这个算法的名字由来是因为越小的元素会经由替换缓缓“浮”到数列的顶端(升序或降序排列),就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”。
实 质:把小(大)的元素往前(后)调
4.2-冒泡排序的剖析和实现(练习)
需要
对数组 { 3, 6, 4, 2, 1, 5 }
进行从小到大的排序。
该数组共6个元素。
图解冒泡算法解析过程
代码实现
经上述图解剖析:代码实现须要
双重循环
- 外层循环,管制躺数(躺数从0开始,因为数组索引从0开始,比拟好计算)。
躺数 = 数组长度 - 1
- 内层循环,管制每趟比拟的次数。
每趟比拟的次数 = 数组的长度 - 以后躺数 - 1
- 外层循环,管制躺数(躺数从0开始,因为数组索引从0开始,比拟好计算)。
- 比拟相邻的两个数字,若地位谬误,则两个数字替换
public class Test06 { public static void main(String[] args) { // 定义要排序的数组 int[] arr = {3, 6, 4, 2, 1, 5}; System.out.println("数组排序前:" + showArray(arr)); /** * 冒泡排序 */ for (int i = 0; i < arr.length - 1; i++) { // 外层循环管制躺数 // i示意以后躺数 for (int j = 0; j < arr.length - i - 1; j++) { // 内层循环管制每趟比拟的次数 // 相邻的两个数字开始比拟:arr[j] 和 arr[j+1] if (arr[j] > arr[j + 1]) { // 地位谬误产生替换 int temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } System.out.println("数组排序后:" + showArray(arr)); } /** * 查看数组 */ public static String showArray(int[]arr) { StringBuilder sb = new StringBuilder(); sb.append("{ "); for (int i = 0; i < arr.length; i++) { if (i == arr.length - 1) { sb.append(arr[i]); } else { sb.append(arr[i] + ", "); } } sb.append(" }"); return sb.toString(); }}
执行后果:
/* 数组排序前:{ 3, 6, 4, 2, 1, 5 } 数组排序后:{ 1, 2, 3, 4, 5, 6 }*/
第五章:数组的二分查找
目标:从数组中查问一个元素,比拟高效的查问形式,就是二分查找。
5.1-什么是二分查找(理解)
二分查找也称折半查找(Binary Search),它是一种效率较高的查找办法,然而,折半查找要求查问的数组的元素是有序排列的。
查找过程如下:
- 首先,假如数组中的元素是按升序排列;
- 将数组两头地位记录的元素值与要查找的元素值比拟,如果两者相等,则查找胜利;
- 否则利用两头地位的记录将数组分成前、后两个子数组;
- 如果两头地位记录的元素值大于要查找元素值,则进一步查找前一子数组,否则进一步查找后一子数组。
- 反复以上过程,直到找到满足条件的记录,使查找胜利,或直到子表不存在为止,此时查找不胜利。
5.2-二分查找的剖析和实现(练习)
需要:
从数组{ 2, 5, 9, 10, 18, 20, 24 }
中别离查问出元素5
、20
、3
折半查找,不能简略的除以2,须要确认最小索引和最大索引。因为可能会屡次折半(一次 折半可能查找不胜利),索引最小索引和最大索引可能会变动。所以须要确定以下变量:
最小索引:min = 0
最大索引:max = 数组的长度 - 1
两头索引:(max + min)/2
图解剖析
图解剖析查问元素5的过程:
图解剖析查问元素20的过程:
图解剖析查问元素3(一个不存在的元素)的过程:
论断
对于要查问的元素:
- 折半次数不确定(可能是屡次),应用while循环更简便。
- 折半过程中,若查问的值小于mid地位的值,则更改索引max为:max = mid - 1
- 折半过程中,若查问的值大于mid地位的值,则更改索引min为:min = mid + 1
- 查问胜利,要查问的元素 和 mid值相等时,终止查问。
- 元素中不存在该元素,条件是索引min大于索引max时,终止查问。
代码
public class Test06 { public static void main(String[] args) { // 定义数组 int[]arr = { 2, 5, 9, 10, 18, 20, 24 }; // 查问元素5 int index1 = binarySearch(arr,5); System.out.println("从数组:{ 2, 5, 9, 10, 18, 20, 24 }查问元素5的索引是:" + index1); // 查问元素20 int index2 = binarySearch(arr,20); System.out.println("从数组:{ 2, 5, 9, 10, 18, 20, 24 }查问元素20的索引是:" + index2); // 查问元素3 int index3 = binarySearch(arr,3); System.out.println("从数组:{ 2, 5, 9, 10, 18, 20, 24 }查问元素3的索引是:" + index3); } /** * 二分查找,返回要查找的元素的索引 * @param arr 数组 * @param key 要查问的元素值 * @return 查问的后果,-1示意不存在该元素 */ public static int binarySearch(int[]arr, int key) { // 最小索引初始化为0 int min = 0; // 最大索引初始化为数组的长度 -1 int max = arr.length - 1; // 两头索引 int mid = 0; // 定义查问后的元素的索引,默认为-1,示意不存在该元素 int index = -1; // 循环查问 while (min <= max){ mid = (max + min)/2; if(key > arr[mid]) { min = mid + 1; }else if(key < arr[mid]){ max = mid - 1; }else { index = mid; break; } } return index; }}
查问后果:
/* 从数组:{ 2, 5, 9, 10, 18, 20, 24 }查问元素5的索引是:1 从数组:{ 2, 5, 9, 10, 18, 20, 24 }查问元素20的索引是:5 从数组:{ 2, 5, 9, 10, 18, 20, 24 }查问元素3的索引是:-1*/
第六章:Arrays类
咱们发现操作数组时,不论是排序、二分查找等,每次实现都须要本人剖析写代码。在开发过程中,影响开发效率。所以Java中提供了操作数组的工具类Arrays。
6.1-概述(理解)
java.util.Arrays
此类蕴含用来操作数组的各种办法,比方排序和搜寻等。Arrays类公有润饰构造方法,其所有办法均为静态方法,调用起来非常简单。
6.2-罕用办法(记忆)
理解更多办法可查问API
public static void main(String[] args) { // 定义数组 int[]arr = { 2, 9, 5, 10, 24, 20, 18 }; // 排序 Arrays.sort(arr); // 排序后的数组 System.out.println(Arrays.toString(arr)); // 二分查找元素5的索引 System.out.println(Arrays.binarySearch(arr,5)); // 二分查找元素20的索引 System.out.println(Arrays.binarySearch(arr,20)); // 二分查找元素3的索引 System.out.println(Arrays.binarySearch(arr,3)); }
第七章:正则表达式
在理论开发中,咱们常常会对一些字符串做验证,比方验证邮箱格局、手机号码、身份证号码等。此时,最无效的验证形式就是正则表达式,只须要用正则形容验证规定,而后间接匹配字符串即可。
7.1-概述(理解)
正则表达式是对字符串操作的一种规定,当时定义好一些字符串,这些字符串称为规定字符串,应用规定字符串表白一些逻辑性能。
例如:指定一个字符串704181501@qq.com,判断出这个字符串是否合乎电子邮件的规定。应用字符串String对象的办法是能够实现的,然而非常复杂,若应用正则表达式则会十分的简略实现。
7.2-正则规定-字符类(记忆)
在中括号中定义的字符
7.3-正则规定-预约义字符类(记忆)
预约义字符,具备非凡含意的字符。
留神:对于w、d、W、D 在java中示意时用双杠如\\w
示意,因为在java的字符串中示意本义。
7.4-正则规定-数量词(记忆)
7.5-正则规定-分组(记忆)
分组,就是将多个字符看做一个整体,用小括号示意。
比方:"(李){4}" 示意字符“李”必须呈现四次
比方:"(李小龙){4}" 示意字符"李小龙"必须间断呈现四次
7.6-正则规定-本义符(记忆)
对于,具备非凡含意的字符若示意为一般字符,能够应用本义符\
,如.
就在正则中示意任意字符,但若就是示意为一般的点的话,则须要本义\.
java字符串中示意用\\.
。
7.5-Java中应用正则表达式(练习)
String类matches办法应用正则表达式
办法:boolean matches(String regex)
传递正则表达式规定,检测字符串是否匹配正则表达式规定,匹配返回true。
需要:查看手机号,查看邮件地址。
剖析:
- 手机号:只能1结尾,第二位能够是345678任意一个,第三位开始全数字,总长11位。
- 邮件地址:@后面能够是数字,字母,下划线。@前面是字母和.。
public static void main(String[] args){ //【验证手机号码】 String tel = "13800138000"; // 规定 String telRegex = "1[345678][0-9]{9}"; // 检测 boolean flag = tel.matches(telRegex); System.out.println(flag); //【验证邮件地址】 String email = "lpl2015@vip.qq.com"; String emailReg = "\\w+@(\\w+\\.)+\\w+"; flag = email.matches(emailReg); System.out.println(flag);}
String类split办法应用正则表达式
办法:String[] split(String regex)
传递正则表达式规定,以正则规定对字符串进行切割,返回数组。
public static void main(String[] args){ String str1 = "ab a bbb abc aa c"; //对空格进行切割 String[] strArr =str1.split(" +"); System.out.println(Arrays.toString(strArr)); String str2 = "192.168.1.121"; strArr = str2.split("\\."); System.out.println(Arrays.toString(strArr));}
留神:输入数组元素时会看到存在一个多余空格,Arrays.toString()办法源码中追加的空格。