- 第5章 Java API
- 5.1 字符串类
- 5.1.1 String类的初始化
- 5.1.2 String类的常见操作
- 5.1.3 StringBuffer 类
- 5.1.4 StringBiuld类
- 5.2 System类和RunTime类
- 5.2.1 System类
- 5.2.2 Runtime类
- 5.3 Math类与Random类
- 5.3.1 Math类
- 5.3.2 Random类
- 5.4 日期时间类
- 5.4.1 Instant类
- 5.4.2 LocalData类
- 5.4.3 LocalTime类 与 LocalDataTime类
- 5.4.4 Period类 和 Duration类
- 5.5 包装类
- 5.6 正则表达式
- 5.6.1 元字符
- 5.6.2 Pattern类 和 Matcher类
- 5.6.3 String类对正则表达式的支持
- 【案例 5-1】 模拟订单号生成
- 【案例5-2】 模拟默认密码自动生成
- 【案例5-3】 模拟用户登录
- 【案例 5-4】字符串转换为二进制
- 【案例 5-5】 二月天
5.1.1 String类的初始化字符串类介绍:Java中定义了三个封装字符串的类,分别是String、StringBuffer和StringBuilder,它们位于java.lang包中,并提供了一系列操作字符串的方法,这些方法不需要导包就可以直接使用
1.使用字符串常量直接初始化一个String对象:String str1 = “abc”;
2.使用String类的构造方法初始化字符串对象
| 方法声明 | 功能描述 |
|---|---|
| String() | 创建一个内容为空的字符串 |
| String(String value) | 根据指定的字符串内容创建对象 |
| String(char[] value) | 根据指定的字符数组创建对象 |
| String(byte[] bytes) | 根据指定的字节数组创建对象 |
1.字符串的获取功能:在Java程序中,需要对字符串进行一些获取的操作,如获得字符串长度、获得指定位置的字符等
实例:
1 public class Example02 {
2 public static void main(String[] args) {
3 String s = "ababcdedcba"; // 定义字符串s
4 // 获取字符串长度,即字符个数
5 System.out.println("字符串的长度为:" + s.length());
6 System.out.println("字符串中第一个字符:" + s.charAt(0));
7 System.out.println("字符c第一次出现的位置:" + s.indexOf('c'));
8 System.out.println("字符c最后一次出现的位置:" + s.lastIndexOf('c'));
9 System.out.println("子字符串ab第一次出现的位置:" +
10 s.indexOf("ab"));
11 System.out.println("子字符串ab字符串最后一次出现的位置:" +
12 s.lastIndexOf("ab"));
13 }
14 }
-
str.length -> 获取字符串长度
-
str.chatAt(0) -> 获取字符串第一个字符(注意是从0开始数)
-
str.indexxOf(‘a’) -> 获取字符 ’ a ’ 第一次出现的位置
-
str.lastIndexxOf(‘a’) -> 获取字符 ’ a ’ 最后一次出现的位置
2.字符串转换操作:程序开发中,经常需要对字符串进行转换操作。例如,将字符串转换成数组的形式,将字符串中的字符进行大小写转换等
实例:
1 public class Example03 {
2 public static void main(String[] args) {
3 String str = "abcd";
4 System.out.print("将字符串转为字符数组后的结果:");
5 char[] charArray = str.toCharArray(); // 字符串转换为字符数组
6 for (int i = 0; i < charArray.length; i++) {
7 if (i != charArray.length - 1) {
8 // 如果不是数组的最后一个元素,在元素后面加逗号
9 System.out.print(charArray[i] + ",");
10 } else {
11 // 数组的最后一个元素后面不加逗号
12 System.out.println(charArray[i]);
13
14 }
15 System.out.println("将int值转换为String类型之后的结果:" +
16 String.valueOf(12));
17 System.out.println("将字符串转换成大写之后的结果:" +
18 str.toUpperCase());
19 System.out.println("将字符串转换成小写之后的结果:" +
20 str.toLowerCase());
21 }
22 }
- str.toCharArray -> 字符串转换为数组
- str.toUpperCase - > 字符串内容转换为大写形式
- str.toLowerCase - > 字符串内容转换为小写形式
valueOf()方法有多种重载的形式,float、double、char等其他基本类型的数据都可以通过valueOf()方法转为String字符串类型
3.字符串的替换和去除空格操作:程序开发中,用户输入数据时经常会有一些错误和空格,这时可以使用String类的replace()和trim()方法,进行字符串的替换和去除空格操作
实例:
1 public class Example04 {
2 public static void main(String[] args) {
3 String s = "itcast";
4 // 字符串替换操作
5 System.out.println("将it替换成cn.it的结果:" + s.replace("it",
6 "cn.it"));
7 // 字符串去除空格操作
8 String s1 = " i t c a s t ";
9 System.out.println("去除字符串两端空格后的结果:" + s1.trim());
10 System.out.println("去除字符串中所有空格后的结果:" + s1.replace(" ",
11 ""));
12 }
13 }
- str.replace(“a”,"b) - > 注意顺序,是用后面的替换前面的
- str.trim -> 去除字符串两端空格
- str.replace(" “,”") -> 去除字符串中所有的空格(其实是通过replace语句将空格字符" “用空字符”"替代了)
4.字符串的判断操作:操作字符串时,经常需要对字符串进行一些判断,如判断字符串是否以指定的字符串开始、结束,是否包含指定的字符串,字符串是否为空等
实例:
1 public class Example05 {
2 public static void main(String[] args) {
3 String s1 = "String"; // 声明一个字符串
4 String s2 = "Str";
5 System.out.println("判断是否以字符串Str开头:" +
6 s1.startsWith("Str"));
7 System.out.println("判断是否以字符串ng结尾:" + s1.endsWith("ng"));
8 System.out.println("判断是否包含字符串tri:" + s1.contains("tri"));
9 System.out.println("判断字符串是否为空:" + s1.isEmpty());
10 System.out.println("判断两个字符串是否相等" + s1.equals(s2));
11 }
12 }
- str.starWith(“a”) -> 判断字符串是否以"a"开头
- str.endWith(“b”) -> 判断字符串是否以"b"结束
- str.contains(“c”) -> 判断字符串是否包含"c"
- str.isEmpty() -> 判断字符串是否为空
- str1.equals(str2) -> 判断两个字符串是否相等
在程序中可以通过“==”和equals()两种方式对字符串进行比较,但这两种方式有明显的区别
(1)equals()方法用于比较两个字符串中的字符是否相等
(2)==方法用于比较两个字符串对象的地址是否相同
也就是说,对于两个内容完全一样的字符串对象,使用equals判断的结果是true,使用==判断的结果是false。
5.字符串的截取和分割:在String类中,substring()方法用于截取字符串的一部分,split()方法用于将字符串按照某个字符进行分割
实例:
1 public class Example06 {
2 public static void main(String[] args) {
3 String str = "石家庄-武汉-哈尔滨";
4 // 下面是字符串截取操作
5 System.out.println("从第5个字符截取到末尾的结果:" +
6 str.substring(4));
7 System.out.println("从第5个字符截取到第6个字符的结果:" +
8 str.substring(4, 6));
9 // 下面是字符串分割操作
10 System.out.print("分割后的字符串数组中的元素依次为:");
11 String[] strArray = str.split("-"); // 将字符串转换为字符串数组
12 for (int i = 0; i < strArray.length; i++) {
13 if (i != strArray.length - 1) {
14 // 如果不是数组的最后一个元素,在元素后面加逗号
15 System.out.print(strArray[i] + ",");
16 } else {
17 // 数组的最后一个元素后面不加逗号
18 System.out.println(strArray[i]);
19 }
20 }
21 }
22 }
-
str.substring(3,5) -> 从第四个字符截取到第五个字符(注意第一个参数为下标,第二个参数为位置)
-
str.substring(3) -> 从第四个字符开始一直截取到最后一个字符
-
str.split("-") -> 以"-"为分隔符,将原字符串分割为一段一段的小字符串
(常与 String[] strArry = str.split("-")联用,意在将分割出来的小段字符串依次存入数组)
String字符串在获取某个字符时,会用到字符的索引,当访问字符串中的字符时,如果字符的索引不存在,则会发生StringIndexOutOfBoundsException(字符串角标越界异常)
由于字符串是常量,因此一旦创建,其内容和长度是不可改变的。如果需要对一个字符串进行修改,则只能创建新的字符串。为了对字符串进行修改,Java提供了一个StringBuffer类**(也称字符串缓冲区)**
StringBuffer类和String类最大的区别在于它的内容和长度都是可以改变的。StringBuffer类似一个字符容器,当在其中添加或删除字符时,并不会产生新的StringBuffer对象
实例:
1public class Example08 {
2 public static void main(String[] args) {
3 System.out.println("1、添加------------------------");
4 add();
5 System.out.println("2、删除------------------------");
6 remove();
7 System.out.println("3、修改------------------------");
8 alter();
9 }
10 public static void add() {
11 StringBuffer sb = new StringBuffer(); // 定义一个字符串缓冲区
12 sb.append("abcdefg"); // 在末尾添加字符串
13 System.out.println("append添加结果:" + sb);
14 sb.insert(2, "123"); // 在指定位置插入字符串
15 System.out.println("insert添加结果:" + sb);
16 }
17 public static void remove() {
18 StringBuffer sb = new StringBuffer("abcdefg");
19 sb.delete(1, 5); // 指定范围删除
20 System.out.println("删除指定位置结果:" + sb);
21 sb.deleteCharAt(2); // 指定位置删除
22 System.out.println("删除指定位置结果:" + sb);
23 sb.delete(0, sb.length()); // 清空缓冲区
24 System.out.println("清空缓冲区结果:" + sb);
25 }
26 public static void alter() {
27 StringBuffer sb = new StringBuffer("abcdef");
28 sb.setCharAt(1, 'p'); // 修改指定位置字符
29 System.out.println("修改指定位置字符结果:" + sb);
30 sb.replace(1, 3, "qq"); // 替换指定位置字符串或字符
31 System.out.println("替换指定位置字符(串)结果:" + sb);
32 System.out.println("字符串翻转结果:" + sb.reverse());
33 }
34 }
- 添加操作
- sb.append(“abc”) -> 在字符串尾部追加"abc"
- sb.insert(3,“a”) -> 在下标为3的位置添加"a"
- 删除操作
- sb.delete(1,5) -> 指定位置删除(与String类的1substring方法相似,第一个参数为下标,第二个参数为位置)
- sb.delete(2) -> 指定位置删除,删除下标为2的字符
- sb.delete(0,sb.length) -> 清空缓冲区的操作
- 修改操作
- sb.setChar(1,“a”) -> 指定位置修改,将下标为1的字符修改为"a"
- sb.replace(1,3,“qq”) -> 指定位置修改,将下标1到位置3的字符段修改为"qq"
StringBuilder类也可以对字符串进行修改,StringBuffer类和StringBuilder类的对象都可以被多次修改,并不产生新的未使用对象
StringBuilder类是JDK5中新加的类,它与StringBuffer之间最大不同在于StringBuilder的方法是线程安全的,也就是说StringBuffer不能被同步访问,而StringBuilder可以
StringBuilder类和StringBuffer类、String类有很多相似之处,归纳一下三者的不同
(1)String类表示的字符串是常量,一旦创建后,内容和长度都是无法改变的。而StringBuilder和StringBuffer表示字符容器,其内容和长度可以随时修改
字符串仅用于表示数据类型 -> 使用String类
需要对字符串中的字符进行增删操作 -> 使用StringBuffer与StringBuilder类
有大量字符串拼接操作,不要求线程安全的情况 -> 采用StringBuilder更高效
有大量字符串拼接操作,如果需要线程安全 -> 使用StringBuffer
(StringBuffer多线程安全性大于StringBuilder)
(2)对于euals()方法的使用我们已经有所了解,但是在StringBuffer类与StringBuilder类中并没有被Object类的equals()方法覆盖,也就是说,equals()方法对于StringBuffer类与StringBuilder类来言并不起作用
(3)String类对象可以用操作符“+”进行连接,而StringBuffer类对象之间不能
5.2 System类和RunTime类 5.2.1 System类System类定义了一些与系统相关的属性和方法,它所提供的属性和方法都是静态的,因此,想要引用这些属性和方法,直接使用System类调用即可
System常用的方法:
- arraycopy()方法:
arraycopy()方法用于将数组从源数组复制到目标数组,声明格式如下:
static void arraycopy(Object src,int srcPos,Object dest,
int destPos,int length)
● src:表示源数组。
● dest:表示目标数组。
● srcPos:表示源数组中拷贝元素的起始位置。
● destPos:表示拷贝到目标数组的起始位置。
● length:表示拷贝元素的个数。
在进行数组复制时,目标数组必须有足够的空间来存放拷贝的元素,否则会发生角标越界异常
实例:
1 public class Example10 {
2 public static void main(String[] args) {
3 int[] fromArray = { 10, 11, 12, 13, 14, 15 }; // 源数组
4 int[] toArray = { 20, 21, 22, 23, 24, 25, 26 }; // 目标数组
5 System.arraycopy(fromArray, 2, toArray, 3, 4); // 拷贝数组元素
6 // 打印拷贝后数组的元素
7 System.out.println("拷贝后的数组元素为:");
8 for (int i = 0; i < toArray.length; i++) {
9 System.out.println(i + ": " + toArray[i]);
10 }
11 }
12 }
//指定了从源数组中索引为2的元素开始拷贝,并且拷贝4个元素存放在目标数组中索引为3的位置
2.currentTimeMillis()方法:
currentTimeMillis()方法用于获取当前系统的时间,返回值是long类型的值,该值表示当前时间与1970年1月1日0点0分0秒之间的时间差,单位是毫秒,通常也将该值称作时间戳
实例:
1 public class Example11 {
2 public static void main(String[] args) {
3 long startTime = System.currentTimeMillis();// 循环开始时的当前时间
4 int sum = 0;
5 for (int i = 0; i < 1000000000; i++) {
6 sum += i;
7 }
8 long endTime = System.currentTimeMillis();// 循环结束后的当前时间
9 System.out.println("程序运行的时间为:"+(endTime - startTime)+"毫
10 秒");
11 }
12 }
3.getProperties()和getProperty()方法
System类的getProperties()方法用于获取当前系统的全部属性,该方法会返回一个Properties对象,其中封装了系统的所有属性,这些属性是以键值对形式存在的。getProperty() 方法用于根据系统的属性名获取对应的属性值
(系统的Properties类)
4.gc()方法
在Java中,当一个对象成为垃圾后仍会占用内存空间,时间一长,就会导致内存空间的不足。针对这种情况,Java中引入了垃圾回收机制。有了这种机制,程序员不需要过多关心垃圾对象回收的问题,Java虚拟机会自动回收垃圾对象所占用的内存空间
除了等待Java虚拟机进行自动垃圾回收外,还可以通过调用System.gc()方法通知Java虚拟机立即进行垃圾回收,当一个对象在内存中被释放时,它的finalize()方法会被自动调用,因此可以在类中通过定义finalize()方法观察对象何时被释放
实例
1 class Person {
2 // 下面定义的finalize方法会在垃圾回收前被调用
3 public void finalize() {
4 System.out.println("对象将被作为垃圾回收...");
5 }
6 }
7 public class Example13{
8 public static void main(String[] args) {
9 // 下面是创建了两个Person对象
10 Person p1 = new Person();
11 Person p2 = new Person();
12 // 下面将变量置为null,让对象成为垃圾
13 p1 = null;
14 p2 = null;
15 // 调用方法进行垃圾回收
16 System.gc();
17 for (int i = 0; i < 1000000; i++) {
18 // 为了延长程序运行的时间
19 }
20 }
21 }
Java虚拟机的垃圾回收操作是在后台完成的,程序结束后,垃圾回收的操作也将终止
5.2.2 Runtime类System类还有一个常见的方法exit(int status),该方法用于终止当前正在运行的Java虚拟机,其中参数status用于表示当前发生的异常状态,通常指定为0,表示正常退出,否则表示异常终止
Runtime类用于表示虚拟机运行时的状态,它用于封装JVM虚拟机进程。每次使用java命令启动虚拟机都对应一个Runtime实例,并且只有一个实例,因此在Runtime类定义的时候,它的构造方法已经被私有化了(单例设计模式的应用),对象不可以直接实例化。若想在程序中获得一个Runtime实例,只能通过以下方式:
Runtime run = Runtime.getRuntime();
Runtime类的常用方法
| 方法声明 | 功能描述 |
|---|---|
| getRuntime() | 该方法用于返回当前应用程序的运行环境对象。 |
| exec(String command) | 该方法用于根据指定的路径执行对应的可执行文件 |
| freeMemory**()** | 该方法用于返回Java虚拟机中的空闲内存量,以字节为单位。 |
| maxMemory() | 该方法用于返回Java虚拟机的最大可用内存量。 |
| availableProcessors() | 该方法用于返回当前虚拟机的处理器个数 |
| totalMemory() | 该方法用于返回Java虚拟机中的内存总量 |
Runtime类的使用:
1.获取当前虚拟机信息
Runtime类可以获取当前Java虚拟机的处理器的个数、空闲内存量、最大可用内存量和内存总量的信息
1 public class Example14 {
2 public static void main(String[] args) {
3 Runtime rt = Runtime.getRuntime(); // 获取
4 System.out.println("处理器的个数: " + rt.availableProcessors()+"个
5 ");
6 System.out.println("空闲内存数量: " + rt.freeMemory() / 1024 / 1024
7 + "M");
8 System.out.println("最大可用内存数量: " + rt.maxMemory() / 1024 /
9 1024 + "M");
10 System.out.println("虚拟机中内存总量: " + rt.totalMemory() / 1024 /
11 1024 + "M");
12 }
13 }
2.操作系统进程
Runtime类中提供了一个exec()方法,该方法用于执行一个dos命令,从而实现和在命令行窗口中输入dos命令同样的效果。例如,通过运行“notepad.exe”命令打开一个Windows自带的记事本程序
1 import java.io.IOException;
2 public class Example15{
3 public static void main(String[] args) throws IOException {
4 Runtime rt = Runtime.getRuntime(); // 创建Runtime实例对象
5 rt.exec("notepad.exe"); // 调用exec()方法
6 }
7 }
查阅API文档会发现,Runtime类的exec()方法返回一个Process对象,该对象就是exec()所生成的新进程,通过该对象可以对产生的新进程进行管理,如关闭此进程只需调用destroy()方法即可
public class Example {
public static void main(String[] args) throws Exception {
Runtime rt = Runtime.getRuntime(); // 创建一个Runtime实例对象
Process process = rt.exec("notepad.exe");//得到表示进程的Process对象
Thread.sleep(3000); // 程序休眠3秒
process.destroy(); // 杀掉进程
}
}
5.3 Math类与Random类
5.3.1 Math类
| 方法声明 | 功能描述 |
|---|---|
| abs() | 该方法用于计算绝对值 |
| sqrt() | 该方法用于计算方根 |
| ceil(a,b) | 该方法用于计算大于参数的最小整数 |
| floor() | 该方法用于计算小于参数的最小整数 |
| round() | 该方法用于计算小数进行四舍五入后的结果 |
| max() | 该方法用于计算两个数的较大值 |
| min() | 该方法用于计算两个数的较小值 |
| random() | 该方法用于生成一个大于0.0小于1.0的随机值 |
| sqrt() | 该方法用于计算开平方的结果 |
| pow() | 该方法用于计算指数函数的值 |
实例
1public class Example16 {
2 public static void main(String[] args) {
3 System.out.println("计算绝对值的结果: " + Math.abs(-10));
4 System.out.println("求大于参数的最小整数: " + Math.ceil(5.6));
5 System.out.println("求小于参数的最大整数: " + Math.floor(-4.2));
6 System.out.println("对小数进行四舍五入后的结果: " + Math.round(-4.6));
7 System.out.println("求两个数的较大值: " + Math.max(2.1, -2.1));
8 System.out.println("求两个数的较小值: " + Math.min(2.1, -2.1));
9 System.out.println("生成一个大于等于0.0小于1.0随机值: " +
10 Math.random());
11 System.out.println("开平方的结果: "+Math.sqrt(4));
12 System.out.println("指数函数的值: "+Math.pow(2, 3));
13 }
14 }
5.3.2 Random类
Java的java.util包中有一个Random类,它可以在指定的取值范围内随机产生数字
| 方法声明 | 功能描述 |
|---|---|
| Random() | 构造方法,用于创建一个伪随机数生成器 |
| Random(long seed) | 构造方法,使用一个long型的seed种子创建伪随机数生成器 |
Random类的两个构造方法:
其中第一个构造方法是无参的,通过它创建的Random实例对象每次使用的种子是随机的,因此每个对象所产生的随机数不同
如果希望创建的多个Random实例对象产生相同的随机数,则可以在创建对象时调用第二个构造方法,传入相同的参数即可
第一种构造方法:
1 import java.util.Random;
2 public class Example17 {
3 public static void main(String args[]) {
4 Random r = new Random(); // 不传入种子
5 // 随机产生10个[0,100)之间的整数
6 for (int x = 0; x < 10; x++) {
7 System.out.println(r.nextInt(100));
8 }
9 }
10 }
第二种构造方法:
1 import java.util.Random;
2 public class Example18 {
3 public static void main(String args[]) {
4 Random r = new Random(13); // 创建对象时传入种子
5 // 随机产生10个[0,100)之间的整数
6 for (int x = 0; x < 10; x++) {
7 System.out.println(r.nextInt(100));
8 }
9 }
10 }
Random类的nextDouble()方法返回的是0.0和1.0之间double类型的值
nextFloat()方法返回的是0.0和1.0之间float类型的值
nextInt(int n)返回的是0(包括)和指定值n(不包括)之间的值
1 import java.util.Random;
2 public class Example19 {
3 public static void main(String[] args) {
4 Random r1 = new Random(); // 创建Random实例对象
5 System.out.println("产生float类型随机数: " + r1.nextFloat());
6 System.out.println("产生double类型的随机数:" + r1.nextDouble());
7 System.out.println("产生int类型的随机数:" + r1.nextInt());
8 System.out.println("产生0~100之间int类型的随机数:" +
9 r1.nextInt(100));
10 }
11 }
5.4 日期时间类
在开发中经常需要处理日期和时间,Java提供了一套专门用于处理日期时间的API,在日期时间类中了包含LocalDate类、LocalTime类、Instant类、Duration类以及Period类等,这些类都包含在java.time包中
| 类的名称 | 功能描述 |
|---|---|
| Instant | 表示时刻,代表的是时间戳 |
| LocalDate | 不包含具体时间的日期 |
| LocalTime | 不含日期的时间 |
| LocalDateTime | 包含了日期及时间 |
| Duration | 基于时间的值测量时间量 |
| Period | 计算日期时间差异,只能精确到年月日 |
| Clock | 时钟系统,用于查找当前时刻 |
Instant 类代表的是某个时间。其内部是由两个Long字段组成,第一部分保存的是标准Java计算时代(就是1970年1月1日开始)到现在的秒数,第二部分保存的是纳秒数
实例:
1 import java.time.Instant;
2 public class Example20 {
3 public static void main(String[] args) {
4 // Instant 时间戳类从1970 -01 - 01 00:00:00 截止到当前时间的毫秒值
5 Instant now = Instant.now();
6 System.out.println("从系统获取的当前时刻为:"+now);
7 Instant instant = Instant.ofEpochMilli(1000 * 60 * 60 * 24);
8 System.out.println("计算机元年增加毫秒数后为:"+instant);
9 Instant instant1 = Instant.ofEpochSecond(60 * 60 * 24);
10 System.out.println("计算机元年增加秒数后为:"+instant1);
11 System.out.println("获取的秒值为:"+Instant.parse
12 ("2007-12-03T10:15:30.44Z").getEpochSecond());
13 System.out.println("获取的纳秒值为:"+Instant.parse
14 ("2007-12-03T10:15:30.44Z").getNano());
15 System.out.println("从时间对象获取的Instant实例为:"+
16 Instant.from(now));
17 }
18 }
注意秒数和毫秒数的差别(1000,Milli和Second)*
5.4.2 LocalData类LocalData类仅用来表示日期。通常表示的是年份和月份,该类不能代表时间线上的即时信息,只是日期的描述
在LocalData类中提供了两个获取日期对象的方法now()和of(int year, int month, int dayOfMonth)
LocalData还提供了日期格式化、增减年月日等一系列的常用方法
| 方法声明 | 功能描述 |
|---|---|
| getYear**()** | 获取年份字段 |
| getMonth**()** | 使用Month枚举获取月份字段 |
| getMonthValue**()** | 将月份字段从1到12 |
| getDayOfMonth**()** | 获取当月第几天字段 |
| format**(**DateTimeFormatter formatter) | 使用指定的格式化程序格式化此日期。 |
| isBefore**(**ChronoLocalDate other) | 检查此日期是否在指定日期之前。 |
| isAfter**(**ChronoLocalDate other) | 检查此日期是否在指定日期之后。 |
| isEqual**(**ChronoLocalDate other) | 检查此日期是否等于指定的日期。 |
| isLeapYear**()** | 根据ISO培训日历系统规则,检查年份是否是闰年。 |
| 方法声明 | 功能描述 |
|---|---|
| parse**(**CharSequence text) | 从一个文本字获取一个 LocalDate的实例。 |
| parse**(**CharSequence text, DateTimeFormatter formatter) | 使用特定格式化 LocalDate从文本字符串获取 LocalDate的实例。 |
| plusYears**(long** yearsToAdd**)** | 增加指定年份 |
| plusMonths**(long** monthsToAdd**)** | 增加指定月份 |
| plusDays**(long** daysToAdd**)** | 增加指定日数 |
| minusYears**(long** yearsToSubtract**)** | 减少指定年份 |
| minusMonths**(long** monthsToSubtract**)** | 减少指定月份 |
| minusDays**(long** daysToSubtract**)** | 减少指定日数 |
| withYear**(**int year) | 指定年 |
| withMonth**(**int month) | 指定月 |
| withDayOfYear(int dayOfYear) | 指定日 |
实例:
1 import java.time.LocalDate;
2 import java.time.format.DateTimeFormatter;
3 public class Example21 {
4 public static void main(String[] args) {
5 //获取日期时分秒
6 LocalDate now = LocalDate.now();
7 LocalDate of = LocalDate.of(2015, 12, 12);
8 System.out.println("1. LocalData的获取及格式化的相关方法--------");
9 System.out.println("从LocalData实例获取的年份为:"+now.getYear());
10 System.out.println("从LocalData实例获取的月份:"
11 +now.getMonthValue());
12 System.out.println("从LocalData实例获取当天在本月的第几天:"+
13 now.getDayOfMonth());
14 System.out.println("将获取到的Loacaldata实例格式化为:"+
15 now.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日")));
16 System.out.println("2. LocalData判断的相关方法----------------");
17 System.out.println("判断日期of是否在now之前:"+of.isBefore(now));
18 System.out.println("判断日期of是否在now之后:"+of.isAfter(now));
19 System.out.println("判断日期of和now是否相等:"+now.equals(of));
20 System.out.println("判断日期of是否时闰年:"+ of.isLeapYear());
21 //给出一个符合默认格式要求的日期字符串
22 System.out.println("3. LocalData解析以及加减操作的相关方法---------");
23 String dateStr="2020-02-01";
24 System.out.println("把日期字符串解析成日期对象后为"+
25 LocalDate.parse(dateStr));
26 System.out.println("将LocalData实例年份加1为:"+now.plusYears(1));
27 System.out.println("将LocalData实例天数减10为:"
28 +now.minusDays(10));
29 System.out.println("将LocalData实例指定年份为2014:"+
30 now.withYear(2014));
31 }
32 }
5.4.3 LocalTime类 与 LocalDataTime类
LocalTime类用来表示时间,通常表示的是小时分钟秒。与LocalData类一样,该类不能代表时间线上的即时信息,只是时间的描述。在LocalTime类中提供了获取时间对象的方法,与LocalData用法类似。
同时LocalTime类也提供了与日期类相对应的时间格式化、增减时分秒等常用方法,这些方法与日期类相对应
1 import java.time.LocalTime;
2 import java.time.format.DateTimeFormatter;
3 public class Example22 {
4 public static void main(String[] args) {
5 // 1. 获取当前时间,包含毫秒数
6 LocalTime time = LocalTime.now();
7 LocalTime of = LocalTime.of(9,23,23);
8 System.out.println("从LocalTime获取的小时为:"+time.getHour());
9 System.out.println("将获取到的LoacalTime实例格式化为:"+
10 time.format(DateTimeFormatter.ofPattern(" HH:mm:ss")));
11 System.out.println("判断时间of是否在now之前:"+of.isBefore(time));
12 System.out.println("将时间字符串解析为时间对象后为:"+
13 LocalTime.parse("12:15:30"));
14 System.out.println("从LocalTime获取当前时间,不包含毫秒数:"+
15 time.withNano(0));
16 }
17 }
5.4.4 Period类 和 Duration类
1.Duration类
Duration类基于时间值,其作用范围是天、时、分、秒、毫秒和纳秒
| 方法声明 | 功能描述 |
|---|---|
| between**(Temporal startInclusive,** Temporal endExclusive**)** | 获取一个Duration表示两个时间对象之间的持续时间。 |
| toDays(): | 将时间转换为以天为单位的 |
| toHours(): | 将时间转换为以时为单位的 |
| toMinutes(): | 将时间转换为以分钟为单位的 |
| toMillis()****: | 将时间转换为以毫秒为单位的 |
| tonanos(): | 将时间转换为以纳秒为单位的 |
实例
1 import java.time.Duration;
2 import java.time.LocalTime;
3 public class Example24{
4 public static void main(String[] args) {
5 LocalTime start = LocalTime.now();
6 LocalTime end = LocalTime.of(20,13,23);
7 Duration duration = Duration.between(start, end);
8 //间隔的时间
9 System.out.println("时间间隔为:"+duration.toNanos()+"纳秒");
10 System.out.println("时间间隔为:"+duration.toMillis()+"毫秒");
11 System.out.println("时间间隔为:"+duration.toHours()+"小时");
12 }
13 }
2.Period类
Period主要用于计算两个日期的间隔,与Duration相同,也是通过between计算日期间隔,并提供了获取年月日的三个常用方法,分别是 getYears()、getMonths()和getDays()
实例:
1 import java.time.LocalDate;
2 import java.time.Period;
3 public class Example25 {
4 public static void main(String[] args) {
5 LocalDate birthday = LocalDate.of(2018, 12, 12);
6 LocalDate now = LocalDate.now();
7 //计算两个日期的间隔
8 Period between = Period.between(birthday, now);
9 System.out.println("时间间隔为"+between.getYears()+"年");
10 System.out.println("时间间隔为"+between.getMonths()+"月");
11 System.out.println("时间间隔为"+between.getDays()+"天");
12 }
13 }
5.5 包装类
Java是一种面向对象的语言,Java中的类可以把方法与数据连接在一起,但是Java语言中却不能把基本的数据类型作为对象来处理
而某些场合下可能需要把基本数据类型的数据作为对象来使用,为了解决这样的问题,JDK中提供了一系列的包装类,可以把基本数据类型的值包装为引用数据类型的对象,在Java中,每种基本类型都有对应的包装类
| 基本数据类型 | 对应的包装类 |
|---|---|
| byte | Byte |
| char | Character |
| int | Integer |
| short | Short |
| long | Long |
| float | Float |
| double | Double |
| boolean | Boolean |
包装类和基本数据类型在进行转换时,引入了装箱和拆箱的概念,其中装箱是指将基本数据类型的值转为引用数据类型,反之,拆箱是指将引用数据类型的对象转为基本数据类型
装箱和拆箱的实例:
public class Example{
public static void main(String[] args){
int a = 20;
Integer in = a;//自动装箱
//在创建Integer对象时,将int类型的变量a作为参数传入,从而转为Integer类型
System.out.println(in);
int l = in;//自动拆箱
//在创建基本类型int时,将Integer类型的值in直接赋给l,从而转为int类型
System.out.println(l);
}
}
Integer类除了具有Object类的所有方法外,还有一些特有的方法
| 方法声明 | 功能描述 |
|---|---|
| Integer valueOf**(int i)** | 返回一个表示指定的int值的 Integer 实例 |
| Integer valueOf**(**String s) | 返回保存指定的String的值的 Integer 对象 |
| int parseInt**(**String s) | 将字符串参数作为有符号的十进制整数进行解析 |
| intValue**()** | 将 Integer 类型的值以int类型返回 |
intValue()方法可以将Integer类型的值转为int类型,这个方法可以用来进行手动拆箱操作
parseInt(String s)方法可以将一个字符串形式的数值转成int类型
**valueOf(int i)**可以返回指定的int值为Integer实例
包装类实例
1 public class Example27 {
2 public static void main(String args[]) {
3 Integer num = new Integer(20);//手动装箱
4 int sum = num.intValue() + 10;//手动拆箱
5 System.out.println("将Integer类值转化为int类型后与10求和为:"+ sum);
6 System.out.println("返回表示10的Integer实例为:" +
7 Integer.valueOf(10));
8 int w = Integer.parseInt("20")+32;
9 System.out.println("将字符串转化为整数位:" + w);
10 }
11 }
使用包装类时的注意点:
-
包装类都重写了Object类中的toString()方法,以字符串的形式返回被包装的基本数据类型的值
-
除了Character外,包装类都有valueOf(String s)方法,可以根据String类型的参数创建包装类对象,但参数字符串s不能为null,而且字符串必须是可以解析为相应基本类型的数据,否则虽然编译通过,但运行时会报错
-
除了Character外,包装类都有parseXxx(String s)的静态方法,将字符串转换为对应的基本类型的数据。参数s不能为null,而且同样字符串必须可以解析为相应基本类型的数据,否则虽然编译通过,但运行时会报错
在程序开发过程中,我们会对一些字符串做各种限制,比如我们常见的注册邮箱、手机号等操作,一般都会做限制长度、格式等。而这些做限制的操作就是用正则表达式做到的。所谓的正则表达式就是指一个用来描述或者匹配一系列符合某个语法规则的字符串的单个字符串。其实就是一种规则
5.6.1 元字符| 元字符 | 功能描述 |
|---|---|
| ** | 转义字符,例如"n"匹配"n" |
| ^ | 正则表达式的开头标志 |
| $ | 正则表达式的结尾标志 |
| ***** | 匹配零次或多次 |
| + | 匹配一次或多次 |
| ? | 匹配一次或零次 |
| . | 匹配任意字符 |
| {n} | 匹配n次 |
| {n,} | 至少匹配n次 |
| {n,m} | n<=m,最少匹配n次,最多匹配m次 |
| x|y| | 匹配x或y |
| [xyz] | 字符集合。匹配所包含的任意一个字符 |
| [a-z] | 字符范围。匹配指定范围内的任意字符 |
| 元字符 | 功能描述 |
|---|---|
| [a-zA-Z] | 匹配a到z或Z |
| [a-z] | 字符范围。匹配指定范围内的任意字符 |
| d | 数字:[0-9] |
| D | 非数字: [^0-9] |
| s | 空白字符:[ tnx0Bfr] |
| S | 非空白字符:[^s] |
| w | 单词字符:[a-zA-Z_0-9] |
| b | 单词边界 |
| B | 非单词边界 |
| A | 输入的开头 |
| G | 上一个匹配的结尾 |
| Z | 输入的结尾,仅用于最后的结束符(如果有的话) |
| z | 输入的结尾 |
| b | 单词边界 |
1.Pattern类
Pattern类用于创建一个正则表达式,也可以说创建一个匹配模式
它的构造方法是私有的,不可以直接创建,但可以通过Pattern.complie(String regex)简单工厂方法创建一个正则表达式,具体代码如下所示:
Pattern p=Pattern.compile("w+");
| 方法声明 | 功能描述 |
|---|---|
| split**(**CharSequence input) | 将给定的输入序列分成这个模式的匹配 |
| Matcher matcher**(**CharSequence input) | 创建一个匹配器,匹配给定的输入与此模式 |
| Static boolean matches**(**String regex, CharSequence input) | 编译给定的正则表达式,并尝试匹配给定的输入 |
2.Matcher类
| 方法声明 | 功能描述 |
|---|---|
| boolean matches() | 对整个字符串进行匹配,只有整个字符串都匹配了才返回true |
| boolean lookingAt() | 对前面的字符串进行匹配,只有匹配到的字符串在最前面才返回true |
| boolean find() | 对字符串进行匹配,匹配到的字符串可以在任何位置 |
| int end**()** | 返回最后一个字符匹配后的偏移量 |
| string group**()** | 返回匹配到的子字符串 |
| int start**()** | 返回匹配到的子字符串在字符串中的索引位置 |
实例
1 import java.util.regex.Matcher;
2 import java.util.regex.Pattern;
3 public class Example29 {
4 public static void main(String[] args) {
5 Pattern p=Pattern.compile("\d+");
6 Matcher m=p.matcher("22bb23");
7 System.out.println("字符串是否匹配:"+ m.matches());
8 Matcher m2=p.matcher("2223");
9 System.out.println("字符串是否匹配:"+ m2.matches());
10 System.out.println("对前面的字符串匹配结果为"+ m.lookingAt());
11 Matcher m3=p.matcher("aa2223");
12 System.out.println("对前面的字符串匹配结果为:"+m3.lookingAt());
13 m.find();//返回true
14 System.out.println("字符串任何位置是否匹配:"+ m.find());
15 m3.find();//返回true
16 System.out.println("字符串任何位置是否匹配:"+ m3.find());
17 Matcher m4=p.matcher("aabb");
18 System.out.println("字符串任何位置是否匹配:"+ m4.find());
19 Matcher m1=p.matcher("aaa2223bb");
20 m1.find();//匹配2223
21 System.out.println("上一个匹配的起始索引::"+ m1.start());
22 System.out.println("最后一个字符匹配后的偏移量"+ m1.end());
23 System.out.println("匹配到的子字符串:"+ m1.group());
24 }
25 }
5.6.3 String类对正则表达式的支持
String类提供了3个方法支持正则操作
| 方法声明 | 功能描述 |
|---|---|
| boolean matches(String regex) | 匹配字符串 |
| String replaceAll**(**String regex, String replacement) | 字符串替换 |
| String[] split**(**String regex) | 字符串拆分 |
1 public class Example30{
2 public static void main(String[] args) {
3 String str = "A1B22DDS34DSJ9D".replaceAll("\d+","_");
4 System.out.println("字符替换后为:"+str);
5 boolean te = "321123as1".matches("\d+");
6 System.out.println("字符串是否匹配:"+te);
7 String s [] ="SDS45d4DD4dDS88D".split("\d+");
8 System.out.print("字符串拆分后为:");
9 for(int i=0;i
【案例 5-1】 模拟订单号生成
在超市购物时,小票上都会有一个订单号,而且每个订单号都是唯一的。本例要求编写一个程序,模拟订单系统中订单号的生成。在生成订单号时,使用年月日和毫秒值组合生成唯一订单号。例如,给定一个包括年月日以及毫秒值的数组arr={2020,0504,1101},将其拼接成字符串s:[202005041101],作为一个订单号
【案例5-2】 模拟默认密码自动生成
本例要求编写一个程序,模拟默认密码的自动生成策略,手动输入用户名,根据用户名自动生成默认密码。在生成密码时,将用户名反转即为默认的密码
【案例5-3】 模拟用户登录
在使用一些APP时,通常都需要填写用户名和密码。用户名和密码输入都正确才会登录成功,否则会提示用户名或密码错误。
本例要求编写一个程序,模拟用户登录。程序要求如下:
(1)用户名和密码正确,提示登录成功。
(2)用户名或密码不正确,提示“用户名或密码错误”
(3)总共有3次登录机会,在3次内(包含三次)输入正确的用户名和密码后给出登录成功的相应提示。超过3次用户名或密码输入有误,则提示登录失败,无法再继续登录。。
在登录时,需要比较用户输入的用户名密码与已知的用户名密码是否相同,本案例可以使用Scanner类以及String类的相关方法实现比较操作
【案例 5-4】字符串转换为二进制
本例要求编写一个程序,从键盘录入一个字符串,将字符串转换为二进制数。在转换时,将字符串中的每个字符单独转换为一个二进制数,将所有二进制数连接起来进行输出。
案例在实现时,要求使用Math类、String类以及Scanner等常见Java API的常用方法实现
【案例 5-5】 二月天
二月是一个有趣的月份,平年的二月有28天,闰年的二月有29天。闰年每四年一次,在判断闰年时,可以使用年份除以4,如果能够整除,则该年是闰年。
本例要求编写一个程序,从键盘输入年份,根据输入的年份计算这一年的2月有多少天。在计算二月份天数时,可以使用日期时间类的相关方法实现。



