Java基础关键_011_ String 类与正则表达式(二)

目 录

一、正则表达式

1.说明

2.应用

[3. 相关方法](#3. 相关方法)

[(1)replace(CharSequence target, CharSequence replacement)](#(1)replace(CharSequence target, CharSequence replacement))

[(2)replaceAll(String regex, CharSequence replacement)](#(2)replaceAll(String regex, CharSequence replacement))

[(3)split(String regex)](#(3)split(String regex))

[(4)matches(String regex)](#(4)matches(String regex))

二、常见问题

1.字符串比较

(1)问题1

(2)问题2

(3)问题3

(4)问题4

(5)问题5

(6)问题6

(7)问题7

2.创建对象个数

(1)问题1

(2)问题2

3.空指针异常

三、实例

[1.统计字符串中 大小写字母、数字个数](#1.统计字符串中 大小写字母、数字个数)

2.反转字符串

3.统计子字符串出现次数

4.身份证号信息抽取

5.获取两个字符串中最大相同子串

[四、StringBuffer 与 StringBuilder](#四、StringBuffer 与 StringBuilder)

1.说明

[2.StringBuilder 常用方法](#2.StringBuilder 常用方法)

[(1)append(Type date)](#(1)append(Type date))

[(2)delete(int start, int end)](#(2)delete(int start, int end))

[(3)deleteCharAt(int index)](#(3)deleteCharAt(int index))

[(4)insert(int offset, String str)](#(4)insert(int offset, String str))

[(5)replace(int start, int end, String str)](#(5)replace(int start, int end, String str))

(6)reverse()

[(7)setCharAt(int index, char ch)](#(7)setCharAt(int index, char ch))

[(8)setLength(int newLength)](#(8)setLength(int newLength))

3.效率

(1)String

(2)StringBuilder

(3)StringBuffer

(4)说明


一、正则表达式

1.说明

  1. Java、C 等大部分编程语言都支持正则表达式;
  2. 一种用于描述特定模式的表达式,可以匹配、查找、替换文本中与该模式匹配的内容;
  3. regular expression ,简称 regex 或 regexp 。

2.应用

  1. 验证输入内容格式是否合规;
  2. 文本编辑器中的查找和替换;
  3. 数据挖掘和信息提取;
  4. 编写 awk、sed、grep 等脚本语言;
  5. 处理数据和字符串时性能较高,可在开发 Web 应用程序时使用。

3. 相关方法

(1)replace(CharSequence target, CharSequence replacement)

将当前字符串中所有的 target 替换为 replacement ,并返回一个新的字符串。

java 复制代码
public class StringTest {
    public static void main(String[] args) {
        String str = "使一个人的有限的生命,更加有效,也即等于延长了人的生命。".replace("生命", "life");
        System.out.println(str);    // 输出:使一个人的有限的life,更加有效,也即等于延长了人的life。
    }
}

(2)replaceAll(String regex, CharSequence replacement)

将当前字符串中所有符合规则的正则表达式的 regex 替换为 replacement 。

java 复制代码
public class StringTest {
    public static void main(String[] args) {
        // 将字符串中的数字替换为空格
        String str = "q1w2e3r4t5y6u7?!~".replaceAll("\\d", " ");
        System.out.println(str);    // 输出:q w e r t y u ?!~
    }
}

(3)split(String regex)

将当前字符串以某个正则表达式表示的子字符串进行分割,并返回一个子字符串数组。

java 复制代码
public class StringTest {
    public static void main(String[] args) {
        String str = "1945-08-15";
        String[] arr = str.split("-");
        System.out.print("日本无条件投降:");
        for (String s : arr) {
            System.out.print(s + " ");
        }
        // 输出:日本无条件投降:1945 08 15
    }
}

(4)matches(String regex)

判断当前字符串是否符合正则表达式 regex 。

java 复制代码
public class StringTest {
    public static void main(String[] args) {
        String email = "1233953804@qq.com";
        // 正则表达式
        String emailReg = "^[A-Za-z0-9\\u4e00-\\u9fa5]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$";
        // 判断是否匹配
        System.out.println(email.matches(emailReg));    // 输出:true
    }
}

二、常见问题

1.字符串比较

(1)问题1

java 复制代码
public class StringTest {
    public static void main(String[] args) {
        String s1 = "abc";
        String s2 = new String(s1);
        System.out.println(s1 == s2);   // false
        System.out.println(s1.equals(s2));  // true
    }
}

(2)问题2

java 复制代码
public class StringTest {
    public static void main(String[] args) {
        String s1 = "abc";
        String s2 = "a" + "b" + "c";
        System.out.println(s1 == s2);   // true
        System.out.println(s1.equals(s2)); // true
        // 因为编译阶段就完成初始化
    }
}

(3)问题3

java 复制代码
public class StringTest {
    public static void main(String[] args) {
        String s1 = "abc";
        String s2 = "a";
        String s3 = s2 + "bc";
        System.out.println(s1 == s3);   // false
        System.out.println(s1.equals(s3)); // true
    }
}

(4)问题4

java 复制代码
public class StringTest {
    public static void main(String[] args) {
        String s1 = "ab";
        final String s2 = "b";
        String s3 = "a" + s2;
        System.out.println(s1 == s3);   // true
        System.out.println(s1.equals(s3));  // true
    }
}

(5)问题5

java 复制代码
public class StringTest {
    public static void main(String[] args) {
        String s1 = "ab";
        final String s2 = getB();   // 运行时赋值
        String s3 = "a" + s2;
        System.out.println(s1 == s3);   // false
        System.out.println(s1.equals(s3));  // true
    }

    private static String getB() {
        return "b";
    }
}

(6)问题6

java 复制代码
public class StringTest {
    public static void main(String[] args) {
        String s1 = "a3";
        String s2 = "a" + 3;
        System.out.println(s1 == s2);   // true
        System.out.println(s1.equals(s2));  // true
    }
}

(7)问题7

java 复制代码
public class StringTest {
    public static void main(String[] args) {
        String s1 = new String("abc");
        StringBuilder s2 = new StringBuilder("abc");
        System.out.println(s1.equals(s2));  // false
        // 因为两者类型不一致,所以无法比较
    }
}

2.创建对象个数

(1)问题1

java 复制代码
public class StringTest {
    public static void main(String[] args) {
        // 字符串常量池 1 个
        String s1 = "a";
        // 字符串常量池 1 个,堆中 1 个
        String s2 = new String("b");
        // 堆中 2 个,其中一个 StringBuilder 对象,一个 String 对象
        String s3 = s1 + s2;
        // 一共 5 个对象,堆中 3 个,常量池 2 个
    }
}

(2)问题2

java 复制代码
public class StringTest {
    public static void main(String[] args) {
        // 字符串常量池 2 个
        // StringBuilder 1 个
        // 堆中Stringr 3 个
        String s = new String("a") + new String("b");
        // 一共 6 个对象
    }
}

3.空指针异常

java 复制代码
public class StringTest {
    public static void main(String[] args) {
        String s1 = null;
        String s2 = s1 + null;
        System.out.println(s2); // nullnull
        // 不会出现空指针异常,因为底层会调用 valueOf 方法
    }
}

三、实例

1.统计字符串中 大小写字母、数字个数

java 复制代码
public class StringTest {
    public static void main(String[] args) {
        String str = "I am 123 , I Like World 521 .";
        char[] chars = str.toCharArray();
        int bigCount = 0, smallCount = 0, numberCount = 0;
        for (int i = 0; i < chars.length; i++) {
            if (chars[i] >= 'A' && chars[i] <= 'Z') {
                bigCount++;
            }
            if (chars[i] >= 'a' && chars[i] <= 'z') {
                smallCount++;
            }
            if (chars[i] >= '0' && chars[i] <= '9') {
                numberCount++;
            }
        }
        System.out.println("大写字母个数:" + bigCount);   // 大写字母个数:4
        System.out.println("小写字母个数:" + smallCount); // 小写字母个数:9
        System.out.println("数字个数:" + numberCount);  // 数字个数:6
    }
}

2.反转字符串

java 复制代码
public class StringTest {
    public static void main(String[] args) {
        String str = "I like you";
        char[] chars = str.toCharArray();
        for (int i = 0; i < chars.length / 2; i++) {
            char temp = chars[i];
            chars[i] = chars[chars.length - 1 - i];
            chars[chars.length - 1 - i] = temp;
        }
        System.out.println(new String(chars));  // uoy ekil I
    }
}

3.统计子字符串出现次数

java 复制代码
public class StringTest {
    public static void main(String[] args) {
        String str = "ABCDAAD";
        int count = 0, index = 0;
        while ((index = str.indexOf("A")) != -1) {
            str = str.substring(index + 1);
            count++;
        }
        System.out.println(count);  // 3
    }
}

4.身份证号信息抽取

java 复制代码
public class StringTest {
    public static void main(String[] args) {
        String id = "140211202502021224";
        System.out.println("出生年份:" + id.substring(6, 10));  // 出生年份:2025
        System.out.println("出生月份:" + id.substring(10, 12)); // 出生月份:02
        System.out.println("出生日期:" + id.substring(12, 14)); // 出生日期:02
        System.out.println("性别:" + (id.charAt(16) % 2 == 0 ? "女" : "男"));   // 性别:女
    }
}

5.获取两个字符串中最大相同子串

java 复制代码
public class StringTest {
    public static void main(String[] args) {
        String s1 = "abcdefghijklmnopqrstuvwxyz";
        String s2 = "123abcdefghhhjjjkkklll";
        int maxLen = 0, start = 0;
        for (int i = 0; i < s1.length(); i++) {
            for (int j = 0; j < s2.length(); j++) {
                int sameLen = 0;
                while (i + sameLen < s1.length() && j + sameLen < s2.length() && s1.charAt(i + sameLen) == s2.charAt(j + sameLen)) {
                    sameLen++;
                }
                if (sameLen > maxLen) {
                    maxLen = sameLen;
                    start = i;
                }
            }
        }
        System.out.println(s1.substring(start, start + maxLen));    // 输出:abcdefgh
    }
}

四、StringBuffer 与 StringBuilder

1.说明

  1. 可变长度字符串;

  2. 目的是应对频繁进行字符串拼接;

  3. jdk 5 新增 StringBuilder ;

  4. StringBuffer 线程安全,在不考虑线程安全情况下优先选择 StringBuilder ,效率更高;

  5. 在底层是 byte 数组,且没有被 final 修饰。若数组存满,可以创建一个更大的新数组实现扩容,重新指向新数组对象;

  6. 优化:在创建 StringBuilder 对象时,预估字符串长度,给定合适的初始化容量,减少底层数组的扩容;

  7. StringBuilder 默认初始化容量为 16 ;

  8. StringBuilder 扩容策略:从当前容量开始,每次扩容为原来的 2 倍再加 2 。


2.StringBuilder 常用方法

(1)append(Type date)

java 复制代码
public class StringTest {
    public static void main(String[] args) {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("Hello");
        stringBuilder.append('a');
        stringBuilder.append(99);
        stringBuilder.append(true);
        stringBuilder.append(new Object());
        System.out.println(stringBuilder);  // 输出:Helloa99truejava.lang.Object@4eec7777
    }
}

(2)delete(int start, int end)

java 复制代码
public class StringTest {
    public static void main(String[] args) {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("Hello");
        stringBuilder.append('a');
        stringBuilder.append(99);
        stringBuilder.append(true);
        stringBuilder.append(new Object());
        System.out.println(stringBuilder);  // 输出:Helloa99truejava.lang.Object@4eec7777
        stringBuilder.delete(2, 6);
        System.out.println(stringBuilder);  // 输出:He99truejava.lang.Object@4eec7777
    }
}

(3)deleteCharAt(int index)

java 复制代码
public class StringTest {
    public static void main(String[] args) {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("Hello");
        stringBuilder.append('a');
        stringBuilder.append(99);
        stringBuilder.append(true);
        stringBuilder.append(new Object());
        System.out.println(stringBuilder);  // 输出:Helloa99truejava.lang.Object@4eec7777
        stringBuilder.deleteCharAt(3);
        System.out.println(stringBuilder);  // 输出:Heloa99truejava.lang.Object@4eec7777
    }
}

(4)insert(int offset, String str)

java 复制代码
public class StringTest {
    public static void main(String[] args) {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("Hello");
        stringBuilder.append('a');
        stringBuilder.append(99);
        stringBuilder.append(true);
        stringBuilder.append(new Object());
        System.out.println(stringBuilder);  // 输出:Helloa99truejava.lang.Object@4eec7777
        stringBuilder.insert(5, "World");
        System.out.println(stringBuilder);  // 输出:HelloWorlda99truejava.lang.Object@4eec7777
    }
}

(5)replace(int start, int end, String str)

java 复制代码
public class StringTest {
    public static void main(String[] args) {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("Hello");
        stringBuilder.append('a');
        stringBuilder.append(99);
        stringBuilder.append(true);
        stringBuilder.append(new Object());
        System.out.println(stringBuilder);  // 输出:Helloa99truejava.lang.Object@4eec7777
        stringBuilder.replace(8, 15, "StringBuilder~");
        System.out.println(stringBuilder);  // 输出:Helloa99StringBuilder~a.lang.Object@4eec7777
    }
}

(6)reverse()

java 复制代码
public class StringTest {
    public static void main(String[] args) {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("Hello");
        stringBuilder.append('a');
        stringBuilder.append(99);
        stringBuilder.append(true);
        stringBuilder.append(new Object());
        System.out.println(stringBuilder);  // 输出:Helloa99truejava.lang.Object@4eec7777
        stringBuilder.reverse();
        System.out.println(stringBuilder);  // 输出:7777cee4@tcejbO.gnal.avajeurt99aolleH
    }
}

(7)setCharAt(int index, char ch)

java 复制代码
public class StringTest {
    public static void main(String[] args) {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("Hello");
        stringBuilder.append('a');
        stringBuilder.append(99);
        stringBuilder.append(true);
        stringBuilder.append(new Object());
        System.out.println(stringBuilder);  // 输出:Helloa99truejava.lang.Object@4eec7777
        stringBuilder.setCharAt(0, '5');
        System.out.println(stringBuilder);  // 输出:5elloa99truejava.lang.Object@4eec7777
    }
}

(8)setLength(int newLength)

java 复制代码
public class StringTest {
    public static void main(String[] args) {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("Hello");
        stringBuilder.append('a');
        stringBuilder.append(99);
        stringBuilder.append(true);
        stringBuilder.append(new Object());
        System.out.println(stringBuilder);  // 输出:Helloa99truejava.lang.Object@4eec7777
        stringBuilder.setLength(5);
        System.out.println(stringBuilder);  // 输出:Hello
    }
}

3.效率

(1)String

java 复制代码
public class StringTest {
    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        String s = "";
        for (int i = 0; i < 100000; i++) {
            s += i;
        }
        long end = System.currentTimeMillis();
        System.out.println("耗时:" + (end - start) + "毫秒");   // 耗时:3347毫秒
    }
}

(2)StringBuilder

java 复制代码
public class StringTest {
    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        StringBuilder sb = new StringBuilder(100000);
        for (int i = 0; i < 100000; i++) {
            sb.append(i);
        }
        long end = System.currentTimeMillis();
        System.out.println("耗时:" + (end - start) + "毫秒");   // 耗时:8毫秒
    }
}

(3)StringBuffer

java 复制代码
public class StringTest {
    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        StringBuffer sb = new StringBuffer(100000);
        for (int i = 0; i < 100000; i++) {
            sb.append(i);
        }
        long end = System.currentTimeMillis();
        System.out.println("耗时:" + (end - start) + "毫秒");   // 耗时:8毫秒
    }
}

(4)说明

String 拼接中,底层会新建一个 StringBuilder 对象,调用其 append()方法进行追加。之后在调用 StringBuilder 的 toString()方法转换为 String 类型,会导致频繁创建 String 对象,效率极低,同时 GC 也面临巨大负荷。

相关推荐
灰色人生qwer7 分钟前
SpringBoot项目注入 traceId 来追踪整个请求的日志链路
java·spring boot·后端·日志·slf4j·链路追踪
我命由我1234524 分钟前
34.Java 阻塞队列(阻塞队列架构、阻塞队列分类、阻塞队列核心方法)
java·服务器·开发语言·后端·架构·java-ee·后端开发
猿周LV28 分钟前
JUC (java. util.concurrent) 的常见类及创建新线程的方法等 [Java EE 初阶]
java·开发语言·java-ee
CN.LG30 分钟前
Spring Boot 与@Bean注解搭配场景
java·spring boot·spring
HPF_9933 分钟前
JVM 简单内存结构及例子
java·jvm
m0_7482489435 分钟前
猿创征文 【高级篇】Java 进阶之JVM实战
java·开发语言·jvm
计算机毕设指导640 分钟前
基于Springboot的小说网站【附源码】
java·开发语言·spring boot·后端·mysql·spring·maven
盖世英雄酱581361 小时前
延迟5个月的回复:编程式事务的传播行为存在并发问题?
java·后端
V+zmm101341 小时前
智慧物流小程序(论文源码调试讲解)
java·数据库·微信小程序·小程序·毕业设计
IDRSolutions_CN2 小时前
(教程)PDF 字体技术入门
java·经验分享·pdf·软件工程·团队开发