字符串介绍
- 字符串被创建后可以理解为是一个字符串对象,左边的引用只是当前字符串变量的管理者(或者叫指针对象),而变量类型(string)则被称为字符串的类,右边则为字符串对象,同时字符串也和数组一样是引用数据类型。
String h= "hello World";
String h = new String("hello world");
String next = scanner.next();
String nextLine = scanner.nextLine();
- 因为字符串也是一种特殊的数组,即也为引用数据类型,所以不可以用字符串的变量名(引用名)对比两个字符串是否相等进行比较,因为字符串引用名存放的实际上是字符串存放的地址,比较字符串名相当于比较字符串存放的地址,两个字符串存放的地址肯定是不同的,所以这样比较返还必为false
String hello2 = new String("Hello World");
String hello3 = new String("Hello World");
System.out.println(hello2 == hello3);
- 和数组一样java也为我们提供了对比两个字符串是否相等的方法
String hello2 = new String("Hello World");
String hello3 = new String("Hello World");
System.out.println(hello2.equals(hello3));
- 同样像数组一样我们也不可以通过赋值字符串变量名来对字符串进行复制
String hello2 = new String("Hello World");
String hello4 = hello2;
System.out.println(hello2 == hello4);
字符串常量池
- 使用
""去定义字符串,这种形式就会被java当成是常量,会被放在常量池当值
- 常量池类似于C语言的全局/静态区 (Global/Static Area)和文字常量区 (Literal Constant Area)
String hello5 = "Hello World";
String hello6 = "Hello World";
- 同时JVM为了减少对于内存空间的浪费会将在常量池中的两个相同的字符串合并到一起,使得多个字符串的字符串名同时指向一块内存空间,如下方代码所示
String hello5 = "Hello World";
String hello6 = "Hello World";
System.out.println(hello5 == hello6);
两种创建字符串的区别
- 实际上使用new关键字的字符串的内容也是存放在常量池中的,当使用
new String("hello") 创建字符串时,尽管字符串字面量 "hello" 存储在字符串常量池中,但 new 关键字会导致在堆上创建一个新的 String 对象。这个对象包含一个指向常量池中 "hello" 的引用。这种方式不会检查字符串常量池中是否已经存在相同的字符串,总是会在堆上创建一个新的对象。

- 而对于字面量创建,当你使用字符串字面量创建字符串时,例如
String s = "hello";,这个字符串实际上是存储在字符串常量池中的。字符串常量池是方法区内的一块内存区域,通常与类的其他信息一起存储。这种方式创建的字符串会检查字符串常量池中是否存在相同的字符串字面量,如果存在,则返回那个字符串的引用;否则,会在常量池中创建一个新的字符串。

字符串可以修改吗
不能直接修改
- 在java中字符串是不可以修改的,无论是字符串字面量创建,还是使用new关键字创建,因为这两种方法一旦创建字符串的值都会放入常量池中,因此在String类中就没有给我们修改字符串的方法
修改字符串的方法
方法一:强制转换为字符型数组
public class ModifyStringExample {
public static void main(String[] args) {
String str = "Hello";
char[] charArray = str.toCharArray();
charArray[1] = 'a';
String modifiedStr = new String(charArray);
System.out.println(modifiedStr);
}
}
方法二:使用StringBuffer或StringBuilder类
- StringBuffer和StringBuilder类是可变字符串类型,允许直接修改字符串字符
- 但两个类性能消耗较大
public class ModifyStringExample {
public static void main(String[] args) {
String str = "Hello";
StringBuilder sb = new StringBuilder(str);
sb.setCharAt(1, 'a');
String modifiedStr = sb.toString();
System.out.println(modifiedStr);
}
}
方法三:使用字符串拼接
public class ModifyStringExample {
public static void main(String[] args) {
String str = "Hello";
String modifiedStr = str.substring(0, 1) + 'a' + str.substring(2);
System.out.println(modifiedStr);
}
}
字符串内置函数(常用操作)
内置函数概念
- 字符串被定义出来的时候可以说是一个String类的对象,每次创建时我们都要使用
new String()来创建对象,在字符串对象中继承了类中的很多方法,我们称之为字符串的内置函数(字符串的常用操作),比如:
System.out.println(hello2.equals(hello3));
System.out.println(hello3.equals(hello2));
字符串的常用内置函数
获取长度
System.out.println(hello2.length());
获取位置
通过字符找下标
- 查到返回下标,没有查到返回-1
- 获取字符/字符串在字符串中第一次出现的位置(下标)
String hello2 = new String("Hello World");
System.out.println(hello2.indexOf('o'));
ystem.out.println(hello2.indexOf("wor"));
- 那想要获得非第一次出现的位置要咋做,实际上只需要给indexof传入一个整型值告诉它从上一次找到的位置开始下一次查找,依次类推
String hello2 = new String("Hello World");
int temp = hello2.indexOf("o");
System.out.print(hello2.indexOf("o",temp+1));
String hello2 = new String("Hello World");
int temp;
temp = hello2.indexOf("o");
while(temp != -1){
System.out.println(temp);
temp = hello2.indexOf("o",temp+1);
}
通过下标找字符
System.out.println(hello2.charAt(4));
替换操作
- 替换操作并不会更改原先的字符串,而是会返回一个替换后的新字符串
String newHello2 = hello2.replace("ld","llld");
System.out.println(newHello2);
截取操作
- 类型于pytho的切片操作,并不会改变原来的字符串而是返回一个新的字符串
String hello2 = new String("Hello World");
System.out.println(hello2.substring(3));
System.out.println(hello2.substring(3,6));
System.out.println(hello2);
转换大小写的操作
- 转换大小写,并不会改变原来的字符串而是返回一个新的字符串
String hello2 = new String("Hello World");
System.out.println(hello2.toUpperCase());
System.out.println(hello2.toLowerCase());
System.out.println(hello2);
