欢迎光临散文网 会员登陆 & 注册

java-u1-day19-正则表达式05(String里面的split方法)

2023-08-17 10:16 作者:刘佛摩尔  | 我要投稿

Day19 字符串和正则表达式

本章重难点

u String的创建

u 字符串常量

u 字符串比较

u 字符串常用方法

u StringBuffer和StringBuilder

u 正则表达式


1. 

String的创建

1.1.  String的创建方式

1)String s1=”abc”; //字符串常量池

2)String s2=new String(“abc”); //栈区有一个字符串引用(地址)指向绑定堆区开盘的字符串对象空间

1.2.  以上两种方式创建字符串,有什么区别?

这个问题要说清楚,必须知道字符串和字符串常量。


2. 

字符串常量

2. 

2.1.  什么是字符串常量池,它放在内存的哪个区?

    就是采用双引号引起来的字符串,不是使用new方式构建的就是字符串常量。字符串常量就是放在方法区的常量池中。常量就是不可以改变的量。

2.2.  案例1

画出两种创建字符串的方式在栈、堆、方法区中的内存结构图。

String str; //栈区有一个字符串引用(地址)

String str = “abc”//栈区有一个字符串引用(地址)绑定或者指向一个常量池内容为abc

 

过程分析:

1) 第1行代码,JVM首先在栈中写入一个引用s1,判断常量池中是否存储abc,如果有,就把abc的首地址赋值给s1,如果没有,就在常量池中新建一个abc,再把首地址赋值给s1.

2) 第2行代码,JVM首先在栈中写入一个引用s2,在堆中通过new String()开辟一块空间,然后把这个空间的首地址赋值给s2的引用。最后在常量池中检查看是否有abc,如果有把abc的首地址赋值给new String()的空间中,如果没有先在常量池中创建,然后再把地址赋值给new String()的空间中。

2.3.  结论

     字符串常量直接指向常量池的首地址,字符串变量是指向堆空间,堆空间指向常量池。

2.4. 案例2

案例:分析下来代码在内存中的结构

String str1 = "str";//常量池

String str2 = "ing";//常量池

String str3 = "str" + "ing";//常量池

String str4 = str1 + str2; //在堆中创建新对象   

String str5 = "string";////常量池

问题:在编码过程中,如果涉及到多个字符串用+进行拼接,这种方式好不好?如果不是最好的方式,应该采用什么方式进行?(引出StringBuffer和StringBuilder)

     不好,他会产生很多的变量在常量池,效率不高,消耗资源。所以,StringBuffer或者是StringBuilder来做拼接,经量少用。


3. 

字符串比较相等

3. 

3.1.  问题1

需求:有如下代码,分析代码的结果。画出内存结果图

String s1 = "abc";

String s2 = "abc";

System.out.println(s1==s2);//true

 

3.2.  问题2

需求:有如下代码,分析代码的结果。画出内存结果图

String s1 =String( "abc");

String s2 =String( "abc");

System.out.println(s1==s2);//false

 

3.3.  字符串比较的结论

1) ==在比较字符串对象的时候用来比较什么?

    比较地址,只适用于字符串常量池

2) 如果要比较内容是否相等,采用什么方式?

   equals():内容是否相等,通过源代码分析,首先比较的是地址是否相等,如果相等就是true,如果地址不相等,就一个字符一个字符对应进行比较。看是否相等,它是重写了Object对象的equals()方法,Object中的equals()比较的是地址。


4. 

字符串对象的方法

4. 

4.1.  String的相关方法

l boolean equals(Object obj):比较字符串的内容是否相同

l boolean equalsIgnoreCase(String str): 比较字符串的内容是否相同,忽略大小写

l boolean startsWith(String str): 判断字符串对象是否以指定的str开头

l boolean endsWith(String str): 判断字符串对象是否以指定的str结尾

4.2.  案例3

需求:编写一个测试类,测试这些方法,加深印象

public class StringTest {

    public static void main(String[] args) {

        //1、比较字符串的内容是否相同

        String s1="hello";//常量池

        String s2=new String("hello");//字符串堆内容

        System.out.println(s1.equals(s2));

        //2、比较字符串的内容是否相同,忽略大小写

        String s3="HeLLo";

        System.out.println(s1.equalsIgnoreCase(s3));

        //3、判断字符串对象是否以指定的str开头

        String filename="abc_f.txt";

        System.out.println(filename.startsWith("1abc"));

        //4、判断字符串对象是否以指定的str结尾

        System.out.println(filename.endsWith(".tx1t"));

    }

}

l int length():获取字符串的长度,其实也就是字符个数

l char charAt(int index):获取指定索引处的字符

l int indexOf(String str):获取str在字符串对象中第一次出现的索引

l String substring(int start):从start开始截取字符串

l String substring(int start,int end):从start开始,到end结束截取字符串。包括start,不包括end

l char[] toCharArray():把字符串转换为字符数组

l String toLowerCase():把字符串转换为小写字符串

l String toUpperCase():把字符串转换为大写字符串

4.3.  案例4

需求:编写一个测试类,测试这些方法,加深学员印象

public class StringTest1 {

    public static void main(String[] args) {

        String s1="abcdef";

        //length():获取字符串的长度,其实也就是字符个数

        System.out.println(s1.length());

        //charAt(int index):获取指定索引处的字符

        char c=s1.charAt(1);

        System.out.println(c);

        //int indexOf(String str):获取str在字符串对象中第一次出现的索引

        int index=s1.indexOf("deccc");

        System.out.println(index);

        //String substring(int start):从start开始截取字符串

        String ss=s1.substring(3);//def

        System.out.println(ss);

        String s2=s1.substring(1,3);

        System.out.println(s2);//bc

        //char[] toCharArray():把字符串转换为字符数组

        char[] chars = s1.toCharArray();

        for (int i = 0; i < chars.length; i++) {

            System.out.println(chars[i]);

        }

        //String toLowerCase():把字符串转换为小写字符串

        String v_s1="AvcD45E";

        System.out.println(v_s1.toLowerCase());

       // String toUpperCase():把字符串转换为大写字符串

        System.out.println(v_s1.toUpperCase());

    }

}

4.4.  案例5

需求:获取指定字符串中,大写字母、小写字母、数字的个数。

大写字母:一个字符(char)ch   ch>=’A’ && ch<=’Z’

小写字母:一个字符(char)ch   ch>=’a’ && ch<=’z’

数字:一个字符(char)ch ch>=’0’ && ch<=’9’

1)思路分析和伪代码

   a、字符如何比较大小,在字母表中的先后顺序;字符本身在计算机中的内存中用数字来描述的。

   b、可以将字符串转成字符数组,然后循环比较它的范围,如果在'a'-'z',这就是小写字母;如果在'A'-'Z'这是大写字母,在'0'-'9'返回就是数字。外面用几个计数器来计数就可以了

2)编码实现

public class StringTest2 {

    public static void main(String[] args) {

        String s="12CRcyuAdwDF09Km";

        //1、将字符串转成字符数组

        char[] chars = s.toCharArray();

        //2、定义3个计数器

        int m=0;//计数小写字母

        int n=0;//计数大写字母

        int k=0;//计数数字

        for (char c:chars){

           if(c>='a'&&c<='z'){

               m++;

           }

            if(c>='A'&&c<='Z'){

                n++;

            }

            if(c>='0'&&c<='9'){

                k++;

            }

        }

        System.out.println("小写字母:"+m+" 大写字母:"+n+" 数字:"+k);

    }

}


5. 

StringBuffer和StringBuilder

问题:String作为字符串使用已经可以满足我们的需要,为什么还会出现现在的这个两个对象?

因为当多个字符串进行连接操作,也就是通过+方法进行拼接字符串的时候,会在常量池中有有过多的临时对象,这样内存中的垃圾很多,我们要解决该问题。所以出现了字符串缓存对象。

 

 

5. 

5.1.  相关知识要点

1)String 是不可变的,StringBuffer、StringBuilder 是可变的;

2)String 、StringBuffer 是线程安全的,StringBuilder 不是线程安全的。

3)StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类

5.2.  StringBuilder的相关方法

    1)append(),追加到字符串的末位

2)insert() 插入到指定位置

3)delete() 删除字符串

4)reverse() 反转

/*

    要点:

        1、StringBuilder对象默认是将字符串放到它的字符数组char[]中的,它的初始的长度是16

        2、该对象是可变的,追加的时候不好在常量池放临时对象,而是放在该对象的字符数组中。

        3、当追加的时候,会计数追加字符串的长度,然后将它+16,作为现在char[]数组的长度

        4、该对象不是字符串,要获得该对象的字符串表示,可以用toString()方法获得字符串

 */

public class StringBuilderTest {

    public static void main(String[] args) {

 

        StringBuilder sb=new StringBuilder("abc");

        //1)append(),追加到字符串的末位

        sb.append("123").append("456").append("yyy");

        System.out.println(sb.toString());

        //2)insert() 插入到指定位置,第1个参数是偏移量,也就是偏移几个字母追加。第2个参数是追加的数据

        sb.insert(1,"zz");

        System.out.println(sb.toString());

        //3)delete() 删除字符串,第1个参数是开始索引,第2个参数是结束索引

        sb.delete(1,3);

        System.out.println(sb.toString());

        //4)reverse() 反转

        sb.reverse();

        System.out.println(sb.toString());

    }

}


6. 

正则表达式

6. 

6.1.  为什么要学习正则表达式?

因为对于某些字符串要进行格式的匹配,这样的需求用传统拆分字符串然后写业务逻辑的方式去处理,业务 逻辑的写法非常复杂。正则表达式可以很方便的做到。而且字符串有专门支持正则表达式进行匹配的方法。我们在使用的时候只要写正则表达式,然后调用字符串的匹配方法就可以完成逻辑的验证操作。

Tip:学习的目的:解决字符串的个性化判断问题,如果没有正则表达式,ifelse就会无穷无尽

6.2.  什么是正则表达式?

又称规则表达式。(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本

6.3.  相关规则

A、规定字符(每一个)出现的内容

0-9之间的数字:\d   [0-9]

字母和数字:  \w  [a-zA-Z0-9]

取反:^        比如描述非数字[^0-9]

出现点号     \\.     

 

B、规定字符串或者字符出现的频率(次数)

? 0次或者1次

+ 1次或者1次以上

* 表示0次或者0次以上

{n} 字符串或者字符出现n次

{n,m} 最少出现n次,最多出现m次

{n,} 出现n次以上包括n次,比如密码长度超过6位:{6,}

6.4.  String字符串的正则表达式的方法

1) matches(正则表达式),返回值是boolean

2) replaceAll(字符串,正则),用正则替换字符串中的子串

6.5.  案例6

需求:判断一个字符串是否是手机字符串"13533839778",手机号的规则:

   0.手机号的长度必须是11位:{11}

   1.手机号的第一位必须是1

   2.手机号的第二位:3或4或5或7或8

   3.手机号的剩余九位的每一位都必须是数字

public class RegTest1 {

    public static void main(String[] args) {

        //1、定义字符串存储手机号

        String phone="13533839778";

        //2、定义一个正则表达式

        String reg="1[34578]\\d{9}";

        //3、利用字符串函数进行匹配

        boolean result = phone.matches(reg);

        System.out.println(result);

    }

}

6.6.  案例7

案例:将字符串“abcpof67kkk12kkk5sss”中的数字变成汉字“我们”

1)思路分析

2)编码实现

public class RegTest2 {

    public static void main(String[] args) {

        //1、定义一个等待检查的字符串

        String s = "abcpof67kkk12kkk5sss";

        //2、定义一个正则表达式

        String reg="\\d";

        //3、用字符串的替换方法

        String s1 = s.replaceAll(reg, "我们");

        //4、输出结果

        System.out.println(s1);

    }

}

 

 

6.7.  案例8

需求:注册的时候要求用户输入邮箱,规则是:

 1)字母开头,中间可以是字母数字下划线或$.

 2)接着是@

 3)是字母长度不超过10位

 4).和字母长度不超过3位

 5)后面还可以接一个.字母,长度不能超过3位

   编码验证改邮箱yy_y$_222y@sina.com.cn是否合法

public class RegTest3 {

    public static void main(String[] args) {

        String email="yy_y$_222y@sina.com.cn";

        String reg="[a-zA-Z][\\w_$]{5,}@[a-zA-Z]{1,10}(\\.[a-zA-Z]{2,3}){1,2}";

        boolean result = email.matches(reg);

        System.out.println(result);

    }

}


7. 

课后作业

1) 完成本章演示案例


java-u1-day19-正则表达式05(String里面的split方法)的评论 (共 条)

分享到微博请遵守国家法律