文章目录
- 前言
- 一、java中的 == 究竟比较的是什么?
- 二、字符串
- 1 String
- (1)String的两种构造方式
- (2)字符数组转字符串、字节数组转字符串
- (3)字符串的 + 拼接
- (4)字符串的内存结构
- (5)字符串的比较
- s.equals(要比较的字符串):不忽略大小写比较(比较内容)
- s.equalsIgnoreCase(要比较的字符串):不忽略大小写比较(比较内容)
前言
一、java中的 == 究竟比较的是什么?
Python中 == 究竟在比较什么?参考博客
- 对于基本数据类型(如int, char等),== 比较的是它们的值。
因为java中的基本数据类型是直接存在栈空间,存的直接就是值,他们压根就没有地址,自然只能比较值,不能比较引用了 - 对于对象类型(如String, List等),== 比较的是它们的内存地址。
对于String还有一点小细节留到 下面字符串的比较里面去说明
二、字符串
java为我们提供了很多的字符串API接口,常见的有·String 、StringBuilder、StringJomier等等
1 String
【注】:
1 开始学习字符串前,我们需要知道在java中字符串String是引用数据类型,并且是不可变的,这个不可变单独解释一下,java中的字符串对象一旦创建就不可变,要修改只能重新创建一个字符串对象重新绑定变量。
2 String这个类是定义在java最基本的类java.lang包下的,并且不需要手动导入就可以用
3 String是一个类,实例化就是对象,下面会有具体演示
String是Java中的一种特殊的引用类型,但是为了方便使用,Java设计了字符串字面量(string literals)和String对象之间的自动转换。这使得我们可以像使用基本数据类型一样使用String,而无需显式地创建对象实例。
字符串字面量:在Java中用双引号括起来的字符串字面量(例如:“Hello”)会被自动转换为String对象。
最后关于 int这些为什么能直接声明变量,不用想了,这肯定是java的语法设计,java虚拟机识别到这种语法就会内部自动进行一些操作就是了,不用想太多,这种就纯粹就是一种语法了。(看完下面String的两种构造方式就知道基本舒服了关于这个疑惑)
(1)String的两种构造方式
前面讲对象实例化语法有下面两句话
- 对象通用实例化语法:类名 变量(对象)名 = new 类名(参数)
除了少部分特殊类(String等),有更加简单的实例化方法,都能使用这个通用的实例化语法(不管你有没有更加简单实例化语法,反正这个一定行)
这里就专门来讲String的两种不同实例化语法了
- 简单实例化语法(用习惯了,今后也更加常用(直接创建)):String s = “hello world”
Java设计了字符串字面量(string literals)和String对象之间的自动转换。这使得我们可以像使用基本数据类型一样使用String,而无需显式地创建对象实例。— Python中万物皆对象,列表、元组、字典这些对象实例化的语法都有这种自动转换机制。 - 通用实例化语法(通过new创建):String s = new String(“hello world”) ,另外,如果括号里面不传参数就是创建空字符串
显式地创建对象实例,当然还是可以的。
// 1. 简单常用String实例化方式
String s1 = "hello";
System.out.println(s1); // hello// 2. 通用使用new关键字(类)实例化String对象方式
String s2 = new String("hello world");
System.out.println(s2); // hello world
(2)字符数组转字符串、字节数组转字符串
下面介绍一种使用字符数组转换成字符串和字节数组转字符串的用法,刷算法题可能会碰到这种用法,这里也提一下。
// 字符数组转字符串
char[] chars = {'a', 'b', 'c', 'd', 'e'};
String str = new String(chars);
System.out.println(str); // abcde// 字节数组转字符串
byte[] bytes = {97, 98, 99, 100, 101};
String str2 = new String(bytes);
System.out.println(str2); // abcde
【注】:需要特别指出如果Python用str([‘a’, ‘b’, ‘c’, ‘d’, ‘e’])会将整个列表转成一个字符串,而不是这种拼接的方式,这是区别
(3)字符串的 + 拼接
前面的练习我们以及知道了,字符串可以和几乎所有类型数据拼接。
System.out.println("Hello World!"+ 1111 + "你好!"); // Hello World!1111你好!
这个功能甚至比Python中的 f " " 这种方式都要好用。
(4)字符串的内存结构
前面已经讲过字符串的两种创建方式:
-
简单实例化语法(直接创建):String s = “hello world”
-
通用实例化语法(通过new创建):String s = new String(“hello world”) ,另外,如果括号里面不传参数就是创建空字符串
下面主要讲直接创建的语法,实际上这种比new更常用是因为在内存结构中更加节省内存。
实际上这种直接创建的方式的String对象会放在堆空间的StringTable(串词)这个区域创建String对象,并且有一个特定就是直接创建的这种方式创建过的字符串分配地址后,如果后面还会创建同样的字符串对象就会直接拿之前的地址来用,不会浪费内存重新创建,而new关键字创建对象会发生这种浪费内存的行为。
直接创建内存图:
记住一点:当使用双引号直接赋值时,系统会检查该字符串在串池中是否存在。
- 不存在:创建新的
- 存在:复用
【特别注意】:上述这个规则对于Python中的整数、字符串这些简单的对象也是适用的,但是对于列表这样比较复杂的对象就不太使用了,反正了解一下这个就可以了,这个内存地址变不变没有什么关系,增加一下奇奇怪怪的知识。
new关键字创建内存图
记住,每new一次就是开辟了一个新的内存空间,每new一次就会产生一个新的地址值。
(5)字符串的比较
在将字符串的比较前,我们需要先了解,java中 == 究竟比的是什么。显然前面我们已经讲过引用数据类型 == 比较的是引用。但是由于String的直接创建和new创建有点小区别在内存上(上面的内存模型),由于直接创建如果是创建已存在的直接复用,但new关键字每new一次就会产生一个新的地址。因此, 二者在混合用时 == 下面有几个细节要注意:
可以看到,这就有问题了。为了解决这种混合用的比较问题,java提供了专门的方法,不比较地址,比较字符串的内容。
s.equals(要比较的字符串):不忽略大小写比较(比较内容)
s.equalsIgnoreCase(要比较的字符串):不忽略大小写比较(比较内容)
String a = "Hello";
String b = "hello";
System.out.println(a.equals(b)); // false
System.out.println(a.equalsIgnoreCase(b)); // true