string内容比较用equals(),避免==;replace()用于字面替换,replaceall()/replacefirst()走正则需转义;split()默认丢弃末尾空串,需用split(",", -1)保留;matches()要求全字符串匹配,子串查找用find()。

String.equals() 和 == 到底怎么选
用 == 比较字符串内容,几乎总出错——它比的是引用地址,不是字符序列。哪怕两个字符串字面值完全一样,只要不是来自字符串常量池或没调用 intern(),== 就可能返回 false。
实操建议:
- 所有语义上的“内容相等”判断,无条件用
equals();比如str1.equals(str2) - 如果
str1可能为null,改用Objects.equals(str1, str2),避免NullPointerException - 只在极少数明确需要判断是否同一对象时(如内部状态标记),才考虑
==,且必须加注释说明意图
replace()、replaceAll()、replaceFirst() 别混用
这三个方法名字像,行为却完全不同:replace() 是纯文本替换,不走正则;后两者底层调用 Pattern.compile(),把第一个参数当正则表达式处理——这意味着传入 "."、"+"、"\d" 之类会意外触发匹配逻辑。
常见错误现象:
立即学习“Java免费学习笔记(深入)”;
-
"a.b".replace(".", "_")→"a_b"(符合直觉) -
"a.b".replaceAll(".", "_")→"_____"(因为.在正则里匹配任意字符) -
"123abc".replaceAll("\d", "X")→"XXXabc"(这才是正则的正确用法)
性能影响:正则版本有编译开销,简单字面替换优先用 replace()。
split() 的坑:空字符串和结尾分隔符
split() 默认会丢弃末尾的空字符串,这和大多数人的直觉相反。比如 "a,b,c,".split(",") 返回长度为 3 的数组 ["a","b","c"],而不是 4 个元素。
使用场景决定要不要保留:
- CSV 解析、协议字段分割等要求严格对齐位置的,必须用带
limit参数的重载:"a,b,c,".split(",", -1)→ 得到 4 个元素 -
limit = 0(默认):丢弃末尾空串,也丢弃开头连续分隔符产生的空串 -
limit > 0:最多切出limit个部分,剩余未切的部分作为最后一个元素
注意:正则特殊字符如 "|"、"+"、"(" 在 split() 第一个参数中必须转义,否则抛 PatternSyntaxException。
正则匹配用 matches() 还是 find()?
String.matches() 要求整个字符串**完全匹配**正则模式,等价于 ^...$ 包裹。想检测子串是否存在、或做多次匹配,不能靠它。
实操建议:
- 校验输入格式(如邮箱、手机号):用
str.matches("^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$") - 提取数字、查找关键词、循环匹配多个结果:必须用
Pattern.compile().matcher(str).find() -
matches()内部每次调用都重新编译正则,高频场景务必预编译Pattern实例复用
容易被忽略的一点:正则引擎对 Unicode 支持默认有限,比如 w 不匹配中文,需要显式加 UNICODE_CHARACTER_CLASS 标志。










