【Java常识】10.0 基本数据类型的自动装箱、拆箱、正则表达
1.0 基本数据类型有专门的包,这算是很常识了。但是有个小知识点,就是涉及自动装箱拆箱。
代码演示如下:
package edp.com.learn1;
public class Demo {
public static void main(String[] args) {
int x = 100;
Integer i1 = new Integer(x); //将基本数据类型包装成对象,装箱。
int y =i1.intValue(); //将对象转化为基本数据类型,拆箱。
//JDK1.5之后
Integer i2 = 100; //自动装箱,把基本数据类型转换为对象。
int z =i2+200; //自动拆箱,把对象转化为基本数据类型。
System.out.println(z);
}
}
执行结果如下:
image.png
这里需要避免空指针异常,比如:
package edp.com.learn1;
public class Demo {
public static void main(String[] args) {
int x = 100;
Integer i1 = new Integer(x); // 将基本数据类型包装成对象,装箱。
int y = i1.intValue(); // 将对象转化为基本数据类型,拆箱。
// JDK1.5之后
Integer i2 = 100; // 自动装箱,把基本数据类型转换为对象。
int z = i2 + 200; // 自动拆箱,把对象转化为基本数据类型。
System.out.println(z);
Integer i3 = null;
int a = i3 + 100;
System.out.println(a);
}
}
执行结果为:
image.png
2.0 正则表达式(英语:Regular Expression,在代码中常简写为regex)。
正则表达式是一个字符串,使用单个字符串来描述、用来定义匹配规则,匹配一系列符合某个句法规则的字符串。在开发中,正则表达式通常被用来检索、替换那些符合某个规则的文本。
字符:
x
含义:代表的是字符x
例如:匹配规则为 "a",那么需要匹配的字符串内容就是 ”a”
字符:
\\
含义:代表的是反斜线字符''
例如:匹配规则为"\" ,那么需要匹配的字符串内容就是 ”\”
字符:
\t
含义:制表符
例如:匹配规则为"\t" ,那么对应的效果就是产生一个制表符的空间
字符:
\n
含义:换行符
例如:匹配规则为"\n",那么对应的效果就是换行,光标在原有位置的下一行
字符:
\r
含义:回车符
例如:匹配规则为"\r" ,那么对应的效果就是回车后的效果,光标来到下一行行首
字符类:
[abc]
含义:代表的是字符a、b 或 c
例如:匹配规则为"[abc]" ,那么需要匹配的内容就是字符a,或者字符b,或字符c的一个
字符类:
[^abc]
含义:代表的是除了 a、b 或 c以外的任何字符
例如:匹配规则为"[^abc]",那么需要匹配的内容就是不是字符a,或者不是字符b,或不是字符c的任意一个字符
字符类:
[a-zA-Z]
含义:代表的是a 到 z 或 A 到 Z,两头的字母包括在内
例如:匹配规则为"[a-zA-Z]",那么需要匹配的是一个大写或者小写字母
字符类:
[0-9]
含义:代表的是 0到9数字,两头的数字包括在内
例如:匹配规则为"[0-9]",那么需要匹配的是一个数字
字符类:
[a-zA-Z_0-9]
含义:代表的字母或者数字或者下划线(即单词字符)
例如:匹配规则为" [a-zA-Z_0-9] ",那么需要匹配的是一个字母或者是一个数字或一个下滑线
预定义字符类:
.
含义:代表的是任何字符
例如:匹配规则为" . ",那么需要匹配的是一个任意字符。如果,就想使用 . 的话,使用匹配规则"\."来实现
预定义字符类:
\d
含义:代表的是 0到9数字,两头的数字包括在内,相当于[0-9]
例如:匹配规则为"\d ",那么需要匹配的是一个数字
预定义字符类:
\w
含义:代表的字母或者数字或者下划线(即单词字符),相当于[a-zA-Z_0-9]
例如:匹配规则为"\w ",,那么需要匹配的是一个字母或者是一个数字或一个下滑线
边界匹配器:
^
含义:代表的是行的开头
例如:匹配规则为^[abc][0-9]$ ,那么需要匹配的内容从[abc]这个位置开始, 相当于左双引号
边界匹配器:
$
含义:代表的是行的结尾
例如:匹配规则为^[abc][0-9]$ ,那么需要匹配的内容以[0-9]这个结束, 相当于右双引号
边界匹配器:
\b
含义:代表的是单词边界
例如:匹配规则为"\b[abc]\b" ,那么代表的是字母a或b或c的左右两边需要的是非单词字符([a-zA-Z_0-9])
数量词:
X?
含义:代表的是X出现一次或一次也没有
例如:匹配规则为"a?",那么需要匹配的内容是一个字符a,或者一个a都没有
数量词:
X*
含义:代表的是X出现零次或多次
例如:匹配规则为"a*" ,那么需要匹配的内容是多个字符a,或者一个a都没有
数量词:
X+
含义:代表的是X出现一次或多次
例如:匹配规则为"a+",那么需要匹配的内容是多个字符a,或者一个a
数量词:
X{n}
含义:代表的是X出现恰好 n 次
例如:匹配规则为"a{5}",那么需要匹配的内容是5个字符a
数量词:
X{n,}
含义:代表的是X出现至少 n 次
例如:匹配规则为"a{5, }",那么需要匹配的内容是最少有5个字符a
数量词:
X{n,m}
含义:代表的是X出现至少 n 次,但是不超过 m 次
例如:匹配规则为"a{5,8}",那么需要匹配的内容是有5个字符a 到 8个字符a之间
举例:校验qq号码.
1: 要求必须是5-15位数字
2: 0不能开头
3:必须都是数字
如果不用正则表达式,代码如下:
package edp.com.learn1;
public class Demo {
public static void main(String[] args) {
System.out.println(checkQQ("012345"));
System.out.println(checkQQ("a1b2345"));
System.out.println(checkQQ("123456"));
System.out.println(checkQQ("1234567890987654321"));
}
public static boolean checkQQ(String qq) {
boolean flag = true;
if (qq.length() >= 5 && qq.length() <= 15) {
if (!qq.startsWith("0")) { // 不能以零开头。
char[] arr = qq.toCharArray();// 将字符串转换成字符数组。
for (int i = 0; i < arr.length; i++) {
char ch = arr[i]; // 记录每一个字符。
if (!(ch >= '0' && ch <= '9')) {
flag = false; // 不是数字。
break;
}
}
} else {
flag = false; //以0开头,不符合qq标准。
}
} else {
flag = false; //长度不符合标准。
}
return flag;
}
}
代码演示:
String qq = "604154942";
String regex = "[1-9][0-9]{4,14}";
boolean flag2 = qq.matches(regex);
完整代码演示:
package edp.com.learn1;
public class Demo {
public static void main(String[] args) {
String regexString = "[1-9]\\d{4,14}";
System.out.println("255255255".matches(regexString));
System.out.println("012345".matches(regexString));
System.out.println("a1b2345".matches(regexString));
System.out.println("1234567890987654321".matches(regexString));
}
}
执行结果:
image.png
举例:校验手机号码
1:要求为11位数字
2:第1位为1,第2位为3、4、5、7、8中的一个,后面9位为0到9之间的任意数字。
代码演示:
String phone = "18800022116";
String regex = "1[34578][0-9]{9}";
boolean flag = phone.matches(regex);
3.0 根据给定正则表达式的匹配规则,拆分此字符串
3.1 基本使用
public String[] split(String regex)
举例:分割出字符串中的的数字
代码演示:
String s = "18-22-40-65";
String regex = "-";
String[] result = s.split(regex);
代码演示:
String s = "18 22 40 65";
String regex = " ";
String[] result = s.split(regex);
3.2 字符串拆分,转换成数组。
当然,这里有一个小细节,放上一段示范代码:
package edp.com.learn1;
public class Demo {
public static void main(String[] args) {
String string = "金秤砣 郭芙蓉 李dayone";
String[] arr = string.split(" "); //空格
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
//如果是通过点来分割,则需要如下处理:
String string2 = "金秤砣.郭芙蓉.李dayone";
String[] arr2 = string2.split("\\.");
System.out.println();
for (int i = 0; i < arr.length; i++) {
System.out.println(arr2[i]);
}
}
}
执行结果为:
image.png
3.3 字符串拆分,转换成数组,排序,并转换为字符串输出。
代码如下:
package edp.com.learn1;
import java.util.Arrays;
public class Demo {
public static void main(String[] args) {
String string = "99 25 45 37 60 ";
//1.将字符串切割成字符串数组。
String[] sArrStrings= string.split(" ");
//2.将字符串转换成数字,并将其存储在一个长度等于int的数组中。
int[] arr= new int[sArrStrings.length];
for (int i = 0; i < arr.length; i++) {
arr[i] = Integer.parseInt(sArrStrings[i]);//将数字字符串转换成数字。
}
//3.排序。
Arrays.sort(arr);
//4.将排序后的结果遍历并拼接成一个字符串。
String string2 = "";
for (int i = 0; i < arr.length; i++) {
if (i==arr.length-1) {
string2 =string2+arr[i];
}else {
string2=string2+arr[i]+" ";
}
}
System.out.println(string2);
}
}
输出结果如下:
image.png
但是,这里存在一个问题,在进行如下运算时,String会不断被新建,持续产生新的垃圾:
String string2 = "";
for (int i = 0; i < arr.length; i++) {
if (i==arr.length-1) {
string2 =string2+arr[i]; //String的拼接底层代码是创建新的String
}else {
string2=string2+arr[i]+" ";
}
}
}
这时候就需要我们用到StringBuilder类。代码如下:
……
//4.将排序后的结果遍历并拼接成一个字符串。
StringBuilder sBuilder = new StringBuilder();
for (int i = 0; i < arr.length; i++) {
if (i==arr.length-1) {
sBuilder.append(arr[i]);
}else {
sBuilder.append(arr[i]+" ");
}
}
System.out.println(sBuilder);
……
这样更加节约内存。
4.0 将符合规则的字符串内容,全部替换为新字符串
public String replaceAll(String regex,String replacement)
举例:把文字中的数字替换成*
代码演示:
String s = "Hello12345World6789012";
String regex = "[0-9]";
String result = s.replaceAll(regex, "*");
或者写成:
String s = "Hello12345World6789012";
String regex = "\\d";
String result = s.replaceAll(regex, "*");
5.0 常用匹配符号
. 任何字符。
\d 数字[0-9]
\D 非数字:[^0-9]
\s 空白字符:[ \t\n\x0B\f\r]
以前dos系统中,\x0B 杠x零b是垂直制表符,\f 翻页,现在可以不用管
\S 非空白字符:[\s]
\w 单词字符:[a-zA-Z_0-9]
\W 非单词字符:[^\w]
这里需要代码演示一下:
package edp.com.learn1;
public class Demo {
public static void main(String[] args) {
// demo1();
String regexString = "[ \\t\\n\\x0B\\f\\r]";
System.out.println("".matches(regexString));
System.out.println(" ".matches(regexString)); //空格
System.out.println("%".matches(regexString));
System.out.println(" ".matches(regexString));//tab键
System.out.println(" ".matches(regexString));//四个空格。
System.out.println();
String regexString2 = "\\s";
System.out.println("".matches(regexString2));
System.out.println(" ".matches(regexString2));//空格
System.out.println("%".matches(regexString2));
System.out.println(" ".matches(regexString2));//tab键
System.out.println(" ".matches(regexString2));//四个空格。
}
public static void demo1() {
String regexString = "\\d";
System.out.println("0".matches(regexString));
}
}
执行结果为:
image.png
6.0 匹配正确的数字
匹配规则:
匹配正整数:”\d+”
匹配正小数:”\d+\.\d+”
匹配负整数:”-\d+”
匹配负小数:”-\d+\.\d+”
匹配保留两位小数的正数:”\d+\.\d{2}”
匹配保留1-3位小数的正数:”\d+\.\d{1,3}”
6.1 匹配合法的邮箱
匹配规则:
”[a-zA-Z_0-9]+@[a-zA-Z_0-9]+(\.[a-zA-Z_0-9]+)+”
等同于如下规格:
”\w+@\w+(\.\w+)+”
6.2 获取IP地址(192.168.1.100)中的每段数字
匹配规则:
”\.”
7.0 数量词匹配
Greedy数量词。
X? X,一次或者一次也没有
X* X,零次一直到多次
X+ X,一次一直多次
X{n} X,恰好n次
X{n,} X,至少n次
X{n,m} X,至少n次,但不超过m次
代码示范如下:
package edp.com.learn1;
public class Demo {
public static void main(String[] args) {
// domo1();
// demo2();
// demo3();
// demo4();
// demo5();
// demo6();
}
public static void demo6() {
String regexString = "[abc]{5,15}";// a或b或c,n次及其以上
System.out.println("abcba".matches(regexString));
System.out.println("aaaaa".matches(regexString));
System.out.println("abcabcabcabcabc".matches(regexString));
System.out.println("abca".matches(regexString));
System.out.println("abcabcabcabcabcc".matches(regexString));
System.out.println("abcd".matches(regexString));
}
public static void demo5() {
String regexString = "[abc]{5,}";// a或b或c,n次及其以上
System.out.println("abcba".matches(regexString));
System.out.println("aaaaa".matches(regexString));
System.out.println("abcabcabcabcabc".matches(regexString));
System.out.println("abca".matches(regexString));
System.out.println("abcd".matches(regexString));
}
public static void demo4() {
String regeString = "[abc]{5}";// a或b或c,恰好n次
System.out.println("abcba".matches(regeString));
System.out.println("aaaaa".matches(regeString));
System.out.println("abcabcabcabcabc".matches(regeString));
System.out.println("abca".matches(regeString));
System.out.println("abcd".matches(regeString));
}
public static void demo3() {
String regeString = "[abc]+";// 一次一直到多次。
System.out.println("".matches(regeString));
System.out.println("a".matches(regeString));
System.out.println("aaabbbccc".matches(regeString));
System.out.println("abcd".matches(regeString));
}
public static void demo2() {
String regeString = "[abc]*";// 零次一直到多次。
System.out.println(" ".matches(regeString));
System.out.println("abc".matches(regeString));
System.out.println("a".matches(regeString));
System.out.println("d".matches(regeString));
System.out.println("aaabbbbccc".matches(regeString));
System.out.println("abcd".matches(regeString));
System.out.println("%".matches(regeString));
}
public static void domo1() {
String regeString = "[abc]?";// 一次或者一次也没有。
System.out.println("a".matches(regeString));
System.out.println("b".matches(regeString));
System.out.println("c".matches(regeString));
System.out.println("d".matches(regeString));
System.out.println("".matches(regeString));
System.out.println("%".matches(regeString));
}
}
8.0 正则表达式的分组功能
上文其实也出现了。凡是有括号的地方,都叫分组。
如下几个案例分析分组功能。
8.1 识别叠词“高高兴兴”、“高兴高兴”等。
代码示范:
package edp.com.learn1;
public class Demo {
public static void main(String[] args) {
// demo1();
// demo2();
}
public static void demo1() {
String regexString = "(.)\\1(.)\\2";
System.out.println("快快乐乐".matches(regexString));
System.out.println("高高兴兴".matches(regexString));
System.out.println("死啦死啦".matches(regexString));
//凡是括号代表组。"\\1"表示第一组又出现一次。
//"\\2"表示第二组又出现一次。
}
public static void demo2() {
String regexString2 = "(..)\\1";
System.out.println("死啦死啦".matches(regexString2));
System.out.println("高兴高兴".matches(regexString2));
System.out.println("快快乐乐".matches(regexString2));
}
}
执行结果:
image.png
8.2 按叠词切割,出现叠词就切割。
String s = "sdqqfgkkkhjppppkl";
//+表示第一组出现一次或多次。
String regexString3 = "(.)\\1+";
String[] arr = s.split(regexString3);
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
8.3 治疗结巴
把“我我....我...我.要...要要...要学....学学..学.编..编编.编.程.程.程..程”字符串还原成“我要学编程”。
代码示范:
String s2 = "我我....我...我.要...要要...要学....学学..学.编..编编.编.程.程.程..程";
//先把点去掉。
String s3 = s2.replaceAll("\\.+", "");
String s4 = s3.replaceAll("(.)\\1+", "$1");
//$1:代表第一组中的内容,获取第一组的数据,并将其整个替换掉。
System.out.println(s4);
执行结果:
image.png
附上完整代码:
package edp.com.learn1;
public class Demo {
public static void main(String[] args) {
// demo1();
// demo2();
// demo3();
demo4();
}
public static void demo4() {
String s2 = "我我....我...我.要...要要...要学....学学..学.编..编编.编.程.程.程..程";
//先把点去掉。
String s3 = s2.replaceAll("\\.+", "");
String s4 = s3.replaceAll("(.)\\1+", "$1");
//$1:代表第一组中的内容,获取第一组的数据,并将其整个替换掉。
System.out.println(s4);
}
public static void demo3() {
String s = "sdqqfgkkkhjppppkl";
//+表示第一组出现一次或多次。
String regexString3 = "(.)\\1+";
String[] arr = s.split(regexString3);
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
public static void demo1() {
String regexString = "(.)\\1(.)\\2";
System.out.println("快快乐乐".matches(regexString));
System.out.println("高高兴兴".matches(regexString));
System.out.println("死啦死啦".matches(regexString));
//凡是括号代表组。"\\1"表示第一组又出现一次。
//"\\2"表示第二组又出现一次。
}
public static void demo2() {
String regexString2 = "(..)\\1";
System.out.println("死啦死啦".matches(regexString2));
System.out.println("高兴高兴".matches(regexString2));
System.out.println("快快乐乐".matches(regexString2));
}
}
9.0 文档补充
在API文档中,有三行代码,作用补充如下:
package edp.com.learn1;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Demo {
public static void main(String[] args) {
Pattern pattern = Pattern.compile("a*b");//获取到正则表达式。a一到多次,b一个。
Matcher matcher = pattern.matcher("aaaaab");//获取匹配器
boolean b = matcher.matches();//看是否能匹配,匹配就返回true。
System.out.println(b);
//以上4行代码,等同于如下代码:
System.out.println("aaaaab".matches("a*b"));
}
}
10.0 从字符串中提取手机号码
package edp.com.learn1;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Demo {
public static void main(String[] args) {
//把一个字符串的手机号码获取出来
String string = "我的手机号码是18588888888,曾经用过18912345678,还用过18887654321";
String regexString ="1[3578]\\d{9}";
Pattern pattern = Pattern.compile(regexString);
Matcher matcher = pattern.matcher(string);
// boolean b1= matcher.find();
// System.out.println(b1);
// String string2 = matcher.group();
// System.out.println(string2);
while (matcher.find()) {
System.out.println(matcher.group());
}
}
}
执行结果:
image.png
END