Linux学习之路Java

【Java常识】10.0 基本数据类型的自动装箱、拆箱、正则表达

2020-01-04  本文已影响0人  bobokaka
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

上一篇下一篇

猜你喜欢

热点阅读