【Java扎马步】String不得不明白的3个点

简介: 版权声明:欢迎转载,请注明沉默王二原创。 https://blog.csdn.net/qing_gee/article/details/60869364 可以证明,String操作是计算机程序设计中最常见的行为。
版权声明:欢迎转载,请注明沉默王二原创。 https://blog.csdn.net/qing_gee/article/details/60869364

可以证明,String操作是计算机程序设计中最常见的行为。——《Java编程思想》

我也可以证明,要想学好Java编程,必须得把String的马步给扎得稳稳的。之前,我自以为有了几年编程经验,觉得String这些老生常谈的话题(比如equals与==)可真是无聊!但事实并非如此,这些基础知识需要反复的传播和推广!

请允许我先举一个例子(请勿对号入座):

有小伙伴在沉默王二技术交流群里发了下面这样一幅图片,问:“我这样判断字符串为空 正确吗?”
这里写图片描述

我没敢轻易下结论,仔仔细细的看了好一遍;先判null,之后把entName放在equals的参数位置判空,我觉得这位小伙的代码写得很完美啊。

但意想不到的是,小伙伴紧接着说:“但是我调试,是null的时候还是进入if ”。
我当时回答说:“那你的调试肯定是瞎调,或者见鬼了。嘿嘿”

我当时诧异极了。幸好之后小伙伴发来debug的截图!
这里写图片描述

你说呢,这样写不报错才怪!
之后我稍解释了一番,并回复说:“建议啊,不是我打击啊,还是多扎扎马步比较好”。
下面我们就细致来说一下String不得不明白的3个点。

1、检查String是否相等

如上文提到的,检查String是否相等最好要使用equals方法,尽量少使用==操作符。

String cmower ="cmower";

System.out.println("cmower" == cmower);//true
System.out.println("cmower".equals(cmower));//true
System.out.println("cmower".substring(0, 3) == "cmo");//false
System.out.println("cmower".substring(0, 3).equals("cmo"));//true
  1. ==操作符确定的是两个String是否放在同一个位置上。
  2. “cmower”字符串和cmower变量指向的引用就是在同一个位置上,所以==比较结果为true。
  3. 在Java虚拟机上,只有字符串常量是共享的(”cmower”字符串和cmower变量共享了同一个地址)。但是对于substring产生的结果就不共享了。
  4. 对于equals,比较的则是两个对象是否具有相同的字符集。

Compares this string to the specified object. The result is true if and only if the argument is not null and is a String object that represents the same sequence of characters as this object.

2、String不可变

public static void main(String[] args) {
    String s = "s";
    String ss = toUpper(s);
    System.out.println(s);//s
    System.out.println(ss);//S
}

private static String toUpper(String b) {
    String bb = b.toUpperCase();

    System.out.println(b);//s
    return bb;
}

“s”是一个字符串对象,你怎么也不能把这个对象变成“S”。也就是说小s和大S尽管是双胞胎,但她们俩注定都不能成为对方。

3、+与StringBuilder

首先,我们先来看对于+操作符,在Java虚拟机下是如何工作的。

public static String add1() {
    String b = "b";
    String s = "a" + b + "c" + "d" + 100;
    return s;
}

public static String add2() {
    String s = "a" + "b" + "c" + "d" + 100;
    return s;
}

对于add1和add2方法,你认为Java虚拟机的工作方式一样吗?

闭上眼睛10秒钟,先想一会。


我们来揭晓答案:
这里写图片描述

差别是不是很大?

这说明,+操作符在拼接String时,会根据情况做一定的选择。比如add1方法,Java会new 一个StringBuilder对象,来对abcd100进行append操作,之后再toString出来。

那么也就说,Java会自动会为我们优化代码,以后我们尽管使用+操作符就行了。但事实并非如此,再来看一串代码。

public static String plus() {
    String result = "";
    for (int i = 0; i < 10; i++) {
        result += "a";
    }
    return result;
}

public static String sb() {
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < 10; i++) {
        sb.append("a");
    }
    return sb.toString();
}

这个时候,你选择用sb方法还是plus方法?

再闭上眼睛10秒钟,想一下你的答案。


javap执行结果如下:
这里写图片描述

看得出plus方法的8-34行是一个循环,11行时创建了StringBuilder对象,也就是在循环内。这个方法执行了10次,那么也就创建了10个StringBuilder对象。

再来看sb方法的结果:
这里写图片描述

显而易见,StringBuilder对象只有一个。

在使用StringBuilder时,尽量少“在append方法的参数中使用+操作符”:

public static String sb1() {
    StringBuilder sb = new StringBuilder();
    String b = "b";
    for (int i = 0; i < 10; i++) {
        sb.append("a" + b);
    }
    return sb.toString();
}

这样做糟糕至极:
这里写图片描述

“a” + b时又重新创建了StringBuilder对象。

总结如下,
1. 在进行循环多次拼接String时,用StringBuilder而不用+操作符!
2. +操作符只用于少量字符串变量拼接,在内存中操作,性能更高!
3. append方法的参数少用+操作符!


最后,留一个话题讨论一下。
对于substring(int beginIndex, int endIndex)方法,在《Java核心技术卷1》上说,endIndex指的是不想复制的第一个位置。但这句话很拗口。我自己也经常搞不清楚到底endIndex该为多少,总是怕搞错,最后非要输出结果确认一下!

问:“如何更好的确定endIndex?”

"cmower".substring(0, 3);

关注“沉默王二”公众号,与你分享IT干货 · 生活感悟 · 读书心得;还有《声音驿站》等着你!
微信扫一扫下方二维码即可关注:

沉默王二

相关文章
|
2月前
|
Java
【Java基础面试三十一】、String a = “abc“; ,说一下这个过程会创建什么,放在哪里?
这篇文章解释了在Java中声明`String a = "abc";`时,JVM会检查常量池中是否存在"abc"字符串,若不存在则存入常量池,然后引用常量池中的"abc"给变量a。
|
2月前
|
Java
【Java基础面试三十二】、new String(“abc“) 是去了哪里,仅仅是在堆里面吗?
这篇文章解释了Java中使用`new String("abc")`时,JVM会将字符串直接量"abc"存入常量池,并在堆内存中创建一个新的String对象,该对象会指向常量池中的字符串直接量。
|
9天前
|
Java 索引
java基础(13)String类
本文介绍了Java中String类的多种操作方法,包括字符串拼接、获取长度、去除空格、替换、截取、分割、比较和查找字符等。
22 0
java基础(13)String类
|
2月前
|
Kubernetes jenkins 持续交付
从代码到k8s部署应有尽有系列-java源码之String详解
本文详细介绍了一个基于 `gitlab + jenkins + harbor + k8s` 的自动化部署环境搭建流程。其中,`gitlab` 用于代码托管和 CI,`jenkins` 负责 CD 发布,`harbor` 作为镜像仓库,而 `k8s` 则用于运行服务。文章具体介绍了每项工具的部署步骤,并提供了详细的配置信息和示例代码。此外,还特别指出中间件(如 MySQL、Redis 等)应部署在 K8s 之外,以确保服务稳定性和独立性。通过本文,读者可以学习如何在本地环境中搭建一套完整的自动化部署系统。
58 0
|
19天前
|
安全 Java API
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
String常量池、String、StringBuffer、Stringbuilder有什么区别、List与Set的区别、ArrayList和LinkedList的区别、HashMap底层原理、ConcurrentHashMap、HashMap和Hashtable的区别、泛型擦除、ABA问题、IO多路复用、BIO、NIO、O、异常处理机制、反射
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
|
19天前
|
存储 安全 Java
Java——String类详解
String 是 Java 中的一个类,用于表示字符串,属于引用数据类型。字符串可以通过多种方式定义,如直接赋值、创建对象、传入 char 或 byte 类型数组。直接赋值会将字符串存储在串池中,复用相同的字符串以节省内存。String 类提供了丰富的方法,如比较(equals() 和 compareTo())、查找(charAt() 和 indexOf())、转换(valueOf() 和 format())、拆分(split())和截取(substring())。此外,还介绍了 StringBuilder 和 StringJoiner 类,前者用于高效拼接字符串,后者用于按指定格式拼接字符串
19 1
Java——String类详解
|
15天前
|
安全 Java
Java StringBuffer 和 StringBuilder 类详解
在 Java 中,`StringBuffer` 和 `StringBuilder` 用于操作可变字符串,支持拼接、插入、删除等功能。两者的主要区别在于线程安全性和性能:`StringBuffer` 线程安全但较慢,适用于多线程环境;`StringBuilder` 非线程安全但更快,适合单线程环境。选择合适的类取决于具体的应用场景和性能需求。通常,在不需要线程安全的情况下,推荐使用 `StringBuilder` 以获得更好的性能。
|
15天前
|
Java 索引
Java String 类详解
Java 中的 `String` 类用于表示不可变的字符序列,是 Java 标准库 `java.lang` 包的一部分。字符串对象一旦创建,其内容不可更改,修改会生成新对象。
|
2月前
|
Java
【Java基础面试二十六】、说一说String和StringBuffer有什么区别
这篇文章区分了Java中的String和StringBuffer类:String是不可变类,一旦创建字符序列就不能改变;而StringBuffer代表可变的字符串,可以通过其方法修改字符序列,最终可以通过`toString()`方法转换为String对象。
【Java基础面试二十六】、说一说String和StringBuffer有什么区别
|
2月前
|
Java API 索引
【Java基础面试二十四】、String类有哪些方法?
这篇文章列举了Java中String类的常用方法,如`charAt()`、`substring()`、`split()`、`trim()`、`indexOf()`、`lastIndexOf()`、`startsWith()`、`endsWith()`、`toUpperCase()`、`toLowerCase()`、`replaceFirst()`和`replaceAll()`,并建议面试时展示对这些方法的熟悉度,同时深入理解部分方法的源码实现。
【Java基础面试二十四】、String类有哪些方法?
下一篇
无影云桌面