字符串和正则表达式
字符串
字符串的分类
不可变字符串:
对应的类:String.
特点:字符串本身不能发生改变,与指向字符串的引用无关.
直接使用"",创建的是不可变字符串
可变字符串:
对应的类:StringBuilder/StringBuffer.
特点:字符串本身可以发生变化,与指向可变字符串的引用无关
创建可变字符串
StringBuffer stringBuffer = new StringBuffer(“hello world”);
图示

字符串的内存分析
字符串, 是一个引用数据类型。 但是字符串的引用, 和之前在面向对象部分的引用有一点差
别。
差别: 类的对象, 是直接在堆上开辟的空间。 字符串, 是在 常量池 中开辟的空间。 (常量池, 是在方法区中的一个子空间)
字符串类型, 之所以选择在常量池中进行空间的开辟, 而不是在堆上。 原因是需要使用 享元原则 。
String str = new String(“hello world”);
String是一个Java中用来描述字符串的类, 里面是有构造方法的。
通过String类提供的构造方法, 实例化的字符串对象, 在堆上开辟的空间。 在堆空间中, 有一个内部维护的属性,指向了常量池中的某一块空间。
尽量使用equals进行String的比较
字符串拼接的内存地址分析
直接使用两个字符串字面量进行拼接
其实,就是直接将两个由双引号直接括起来的字符串进行拼接 。类似于 String str= “hello” + “world”; 。
这里,直接在常量池中进行空间操作。将常量池中拼接之后的结果, 地址给 str 进行赋值。
使用一个字符串变量和其他的进行拼接
String s = new String(“hello”);
String s1 = s + “world”;
这里的拼接,不是在常量池中直接完成的。
在这个拼接的过程中, 隐式的实例化了一个String类的对象, 在堆上开辟了空间。堆上空间内部维护了一个指向了常量池中拼接结果的一个属性。 这个堆上的空间地址给左侧的引用进行了赋值。
字符串的常用方法
字符串的构造方法(列举)

字符串的非静态方法
因为字符串, 是常量。 任何的修改字符串的操作, 都不会对所修改的字符串造成任何的影响。 所有的对字符串的修改操作, 其实都是实例化了新的字符串对象。 在这个新的字符串中, 存储了修改之后的结果。 并将这个新的字符串以返回值的形式返回。 所以, 如果需要得到对一个字符串修改之后的结果, 需要接收方法的返回值。



字符串的静态方法

StringBuffer和StringBuilder类
概念
都是用来操作字符串的类,我们成为可变字符串
字符串都是常量, 所有的操作字符串的方法, 都不能直接修改字符串本身。 如果我们需要得到修改之后的结果, 需要接收返回值。
StringBuffer和StringBuilder不是字符串类, 是用来操作字符串的类。 在类中维护了一个字符串的属性, 这些字符串操作类中的方法, 可以直接修改这个属性的值。 对于使用方来说,可以不去通过返回值获取操作的结果。
在StringBuffer或者StringBuilder类中, 维护了一个字符数组。 这些类中所有的操作方法,都是对这个字符数组进行的操作。
常用方法

. 区别
StringBuffer和StringBuilder从功能上来讲, 是一模一样的。 但是他们两者还是有区别的:
StringBuffer是线程安全的。
StringBuilder是线程不安全的。
使用场景:
当处于多线程的环境中, 多个线程同时操作这个对象, 此时使用StringBuffer。
当没有处于多线程环境中, 只有一个线程来操作这个对象, 此时使用StringBuilder。
备注
但凡是涉及到字符串操作的使用场景, 特别是在循环中对字符串进行的操作。 一定不要使用字符串的方法, 用StringBuffer或者StringBuilder的方法来做。
由于字符串本身是不可变的, 所以String类所有的修改操作, 其实都是在方法内实例化了一个新的字符串对象, 存储拼接之后的新的字符串的地址, 返回这个新的字符串。 如果操作比较频繁, 就意味着有大量的临时字符串被实例化、被销毁, 效率极低。 StringBuffer、StringBuilder不同, 在内部维护了一个字符数组, 所有的操作都是围绕这个字符数组进行的操作。 当需要转成字符串的时候, 才会调用 toString() 方法进行转换。 当频繁用到字符串操作的时候, 没有中间的临时的字符串出现, 效率较高。
正则表达式
正则表达式的使用
实现相同的功能, 用String、StringBuffer、StringBuilder可以实现, 用正则表达式也可以实现。
但是在实现过程中, 复杂程度是完全不一样的。
基本的元字符
正则表达式的匹配规则
逐个字符进行匹配, 判断是否和正则表达式中定义的规则一致。
以下借助 String 类中的 matches 方法进行正则基础的语法解。
boolean matches(String regex);
是String类中的非静态方法, 使用字符串对象调用这个方法, 参数是一个正则表达式。
使用指定的正则表达式, 和当前的字符串进行匹配。 验证当前的字符串是否和指定的规则是相匹配的。
元字符



字符串的替换
private static void replace() {
// 需求: 将这个存储有所有的名字的字符串,名字之间的分 隔用, 来替代
String names = "lily lucy polly Jim LiLei
HanMeimei";
// 实现: 借助字符串中的一个方法 replaceAll(String regex, String
replacement)
// 将字符串中,满足指定正则的部分,替换成replacement
// String result = names.replaceAll(" +", ", ");
String result = names.replaceFirst(" +", ", ");
System.out.println(result);
}
private static void example() {
// 需求: 将一个手机号的中间4位替换成 ****
// 17788889999 => 177****9999
String phoneNumber = "17788889999";
// 在replace方法中,使用$1获取第一个分组的值
String result = phoneNumber.replaceAll(" (1\\d{2})(\\d{4})(\\d{4})","$1****$3");
System.out.println(result);
}
Pattern和Matcher类
简介
在 java.util.regex 包中
Pattern类: 在Java中,正则表达式的载体。使用正则表达式进行字符串的校验、切割、替换,都需要使用到这个类。
在Java中,使用字符串的形式来写正则表达式。此时,如果需要这个字符串被当做是一个正则表达式使用, 必须先由这样的字符串编译为 Pattern 类的对象。然后才可以使用这个对象的某些方法, 进行常见的操作(校验、切割、替换)。
Matcher类: 在Java中, 对一个正则校验的结果描述。
常用方法
Pattern

Matcher

find()
从字符串的第0位开始查询, 查询是否有满足指定规则的子部分。
当再次调用find()的时候, 从上次查询到的位置开始, 继续向后查询。
关于查询
无论是 matches, 还是find, 还是lookingAt, 在字符串中进行校验、匹配的时候, 是有一个浮标存在的。
示例代码
Pattern 类的使用:
public class Regex1 {
public static void main(String[] args) {
// 1. 静态的校验
boolean ret = Pattern.matches("[1-9]\\d{5,10}", "123456");
System.out.println(ret);
// 2. 将一个字符串编译为正则表达式对象(Pattern对象)
Pattern pattern = Pattern.compile(" +");
// 3. 字符串切割
String[] array1 = pattern.split("Lily Lucy Polly Jim Tom");
System.out.println(Arrays.toString(array1));
String[] array2 = pattern.split("Lily Lucy Polly Jim Tom", 0);
System.out.println(Arrays.toString(array2));
}
}
Matcher:
public class Regex2 {
public static void main(String[] args) {
// 1. 准备一个数据源
String data = "abc123hello world456lily789lucy012uncle111wang";
// 2. 将一个字符串变异成正则对象
Pattern pattern = Pattern.compile("\\d+");
// 3. 使用一个正则和一个字符串进行校验
Matcher matcher = pattern.matcher(data);
// 3.1. 获取整体校验的结果
// 匹配逻辑:
// 从第0个字符开始,判断每一个字符是否否则当前的正则。
// 当找到了有不符合当前正则部分的时候,就会停止继续向后查找,直接返
回false
System.out.println(matcher.matches());
// 3.2. find()
while (matcher.find()) {
System.out.print("匹配到了字符串: " + matcher.group() + ", ");
System.out.println("下标范围: [" + matcher.start() + ", " +
matcher.end() + ")");
}
// 3.3. lookingAt()
System.out.println(matcher.lookingAt() + ", " + matcher.group() +
", [" + matcher.start() + ", " + matcher.end() + ")");
}
}
本文详细探讨了Java中的字符串特性,包括不可变字符串、可变字符串(StringBuilder和StringBuffer)及其内存分析。此外,还深入讲解了正则表达式的使用,基本元字符的匹配规则以及Pattern和Matcher类的应用,强调了在多线程环境下选择合适字符串操作类的重要性。
471

被折叠的 条评论
为什么被折叠?



