Java String 字符串和相关操作

字符串是由字符组成的不可变的Unicode字符序列。即String对象一旦创建,其内容就不能被修改。String类位于java.lang包中,因此不需要导入即可直接使用。

字符串的创建

字符串可以通过多种方式创建:

字面量创建 :最常见的方式是通过双引号(")创建字符串字面量。

ini 复制代码
// 字面量创建
String str1 = "Hello, World!";

构造方法创建 :通过String类的构造方法创建字符串对象。

ini 复制代码
// 方式一:通过String类的构造方法创建 - 最简单的方式
String str2 = new String("Hello, World!");
// 方式二:使用字符创建
char[] chars = {'H', 'e', 'l', 'l', 'o'};
String str3 = new String(chars);
// 方式三:从字节数组创建
byte[] bytes = {'H', 'e', 'l', 'l', 'o'};
String str4 = new String(bytes);
// 方式四:从字节数组的部分范围创建
byte[] moreBytes = {97, 98, 99, 100, 101, 102};
String str5 = new String(moreBytes, 1, 3); // 取从索引1开始的三个字节

字符串特性

  • 不可变性:一旦创建了一个字符串对象,其内容就不能被改变。这意味着每次对字符串进行拼接、替换等操作,都会生成一个新的字符串对象。
  • 字符串池 :Java中有一项优化机制,即字符串池(String Pool),当创建字符串字面量时,JVM会先检查字符串池中是否存在相同的字符串,如果存在则直接引用,否则将新字符串添加到池中。通过intern()方法可以明确将字符串添加至字符串池。

字符串拼接

由于字符串的不可变性,连接字符串时会创建一个新的字符串对象。

ini 复制代码
String part1 = "Java";
String part2 = "Programming";
// 使用加号(+)拼接
String concatenated = part1 + " " + part2;
// 或者使用String.join()方法
String joined = String.join(" ", part1, part2);

数组转字符串: StringBuilder是一个可变的字符序列,它提供了append()方法来高效地拼接字符串。使用StringBuilder可以避免由于字符串不可变性导致的性能问题,特别是在频繁修改字符串内容的情况下。(例如:)

ini 复制代码
String[] Strings = {"a", "b", "c", "d", "e", "f", "g", "h,i,j,k"};
// 创建StringBuilder对象
StringBuilder sb = new StringBuilder();
for (String str : Strings) {
    // 使用append()方法拼接字符串
    sb.append(str);
}
// 将StringBuilder对象转换为字符串
String result = sb.toString();

常用方法

字符串操作

  • length():返回字符串中的字符数量,即字符串的长度。
ini 复制代码
// 创建一个字符串实例
String str = "Hello, World!";
​
// 使用 length() 方法获取字符串长度
int length = str.length();
System.out.println("str的长度: " + length); // 输出:13
  • charAt(int index):返回指定索引位置处的字符。注意,索引是从0开始的。
rust 复制代码
// 创建一个字符串实例
String str = "Hello, World!";
​
// 使用 charAt() 方法获取指定索引位置的字符
char firstChar = str.charAt(0);
System.out.println("str的第一个字符: " + firstChar); // 输出:H
  • substring(int beginIndex, int endIndex):返回一个新字符串,它是原字符串的一部分,从指定的beginIndex起始索引(包含)到endIndex结束索引(不包含)。
rust 复制代码
// 创建一个字符串实例
String str = "Hello, World!";
​
// 使用 substring() 方法获取子串
String subString = str.substring(7, 12);
System.out.println("获取子串: " + subString); // 输出:World
  • concat(String otherString):将当前字符串与提供的字符串拼接起来,形成一个新的字符串,原字符串不会被改变。
rust 复制代码
// 创建一个字符串实例
String str = "Hello, World!";
​
// 使用 concat() 方法连接两个字符串
String appendedStr = str.concat(", 你好 Java!");
System.out.println("concat连接两个字符串: " + appendedStr); // 输出:Hello, World!, 你好 Java!
  • replace(CharSequence target, CharSequence replacement):查找字符串中所有出现的目标序列,并将其替换为给定的新字符串。
rust 复制代码
// 创建一个字符串实例
String str = "Hello, World!";
​
// 使用 replace() 方法替换字符串中的部分字符或子串
String replacedStr = str.replace("World", "Java");
System.out.println("Replaced string: " + replacedStr); // 输出:Hello, Java!

比较

  • equals(Object obj) 或 :比较两个字符串的内容是否相等。区分大小写。
ini 复制代码
String str1 = "hello";
String str2 = "hello";
boolean isEqual = str1.equals(str2);
System.out.println(isEqual); // 输出:true
​
String str3 = "Hello";
boolean isEqualCaseSensitive = str1.equals(str3);
System.out.println(isEqualCaseSensitive); // 输出:false
  • equalsIgnoreCase(String anotherString):类似于 equals() 方法,但它在比较时忽略字符的大小写。
ini 复制代码
String str1 = "hello";
String str3 = "Hello";
boolean isEqualIgnoreCase = str1.equalsIgnoreCase(str3);
System.out.println(isEqualIgnoreCase); // 输出:true
  • compareTo(String anotherString):按照字典顺序比较两个字符串。

    • 返回值如果是正数,则表示当前字符串大于另一个字符串;
    • 返回值如果为负数,则小于另一个字符串;
    • 返回值如果等于0,则表示两者相等;
ini 复制代码
String str1 = "apple";
String str2 = "banana";
int comparisonResult = str1.compareTo(str2);
System.out.println(comparisonResult); // 输出:-1 (因为 'a' 到 'b' 的ASCII差值加上后续字符的差异)
​
String sameStr = "apple";
int sameComparison = str1.compareTo(sameStr);
System.out.println(sameComparison); // 输出:0
  • startsWith(String prefix):检查当前字符串是否以指定的前缀开始。
ini 复制代码
String sentence = "Hello, world!";
boolean startsWithHello = sentence.startsWith("Hello");
System.out.println(startsWithHello); // 输出:true
​
boolean notStartsWithGoodbye = sentence.startsWith("Goodbye");
System.out.println(notStartsWithGoodbye); // 输出:false
  • endsWith(String suffix):检查当前字符串是否以指定的后缀结束。
ini 复制代码
String sentence = "Hello, world!";
boolean endsWithExclamation = sentence.endsWith("!");
System.out.println(endsWithExclamation); // 输出:true
​
boolean notEndsWithQuestion = sentence.endsWith("?");
System.out.println(notEndsWithQuestion); // 输出:false

查找

  • indexOf(int ch) :查找指定字符在字符串中首次出现的索引位置。

    • 如果字符在字符串中存在,则返回它在字符串中的索引(位置从 0 开始计数),空格也会被算进来;
    • 如果字符不存在于字符串中,则返回 -1。
    • ch:这是要查找的字符,以整数形式表示,通常通过 Unicode 编码点(code point)来确定字符。
perl 复制代码
String str = "Hello, World!";
char searchChar = 'W';
        
// 使用 int 值来查找字符 'W' 的索引位置
int index = str.indexOf((int) searchChar);
​
if (index != -1) {
   System.out.println("'" + searchChar + "' 在字符串中的索引位置是: " + index); // 'W' 在字符串中的索引位置是: 7
} else {
  System.out.println("'" + searchChar + "' 不在字符串中");
}
  • indexOf(String str):查找指定字符串在当前字符串中首次出现的位置.

    • 如果找到,返回值是匹配子串的起始索引
    • 如果找不到匹配的子串,则返回 -1
    • str:要在当前字符串中查找的子字符串。
arduino 复制代码
// 创建一个字符串
String fullString = "Hello, welcome to the world of Java programming.";
​
// 定义要查找的子字符串
String searchString = "welcome";
​
// 使用 indexOf 方法查找子字符串的位置
int index = fullString.indexOf(searchString);
​
// 输出结果
if (index != -1) {
   System.out.println("'" + searchString + "' 在 '" + fullString + "' 中的位置是: " + index);
} else {
   System.out.println("'" + searchString + "' 在 '" + fullString + "' 中未找到");
}
  • contains(CharSequence s):判断字符串是否包含指定的字符序列(CharSequence),区分大小写。如果你想进行不区分大小写的检查,可以先将字符串转换为统一的大写或小写再进行比较。

    • CharSequence s:这是一个表示字符序列的接口,它可以是 String 对象或其他实现了 CharSequence 接口的类实例,如 StringBuilderCharBuffer
arduino 复制代码
// 创建一个字符串
String fullString = "Hello, welcome to the world of Java programming.";

// 检查字符串是否包含子字符串 "welcome"
boolean containsWelcome = fullString.contains("welcome");

// 输出结果
System.out.println("'welcome' 是否在 '" + fullString + "' 中? " + containsWelcome);

// 检查字符串是否包含子字符串 "C++"
boolean containsCpp = fullString.contains("C++");

// 输出结果
System.out.println("'C++' 是否在 '" + fullString + "' 中? " + containsCpp);

分割与拼接

  • split(String regex):根据正则表达式分割字符串,返回字符串数组。

    • regex:这是一个正则表达式,用于定义如何分割字符串。例如,. 表示任何字符,\s 表示空白字符,, 表示逗号等。

注意事项:

  • 默认情况下,此方法会尽可能多地进行分割,即贪婪模式。若想限制分割次数,可以使用 split(String regex, int limit) 版本,其中 limit 参数用于指定最大分割片段数。
  • 空字符串作为分隔符不会产生额外的空字符串元素,只有相邻的分隔符才会产生一个空字符串。
arduino 复制代码
// 示例字符串
String str = "Hello,World,Java,Programming";
        
// 使用逗号作为分隔符进行分割
String[] words = str.split(",");
        
// 输出分割后的子字符串数组
for (String word : words) {
    System.out.println(word);
}
  • join(CharSequence delimiter, Iterable<? extends CharSequence> elements):Java 8及以上版本引入的一个便捷方法,用于将一系列字符串(或者实现了 CharSequence 接口的对象)连接成一个单一的字符串,其间用指定的分隔符进行间隔。

    • delimiter:这是一个 CharSequence 类型的对象,代表用于分隔各个元素的字符序列。它可以是一个字符串或者其他任何实现了 CharSequence 接口的对象,比如 StringStringBuilderCharBuffer 等。
    • elements:这是一个实现了 Iterable 接口的对象,通常是一个集合,如 List<String>Set<String> 或者数组,它包含了待连接的元素,这些元素必须是 CharSequence 类型或其子类型。
arduino 复制代码
// 创建一个字符串列表
List<String> fruits = Arrays.asList("Apple", "Banana", "Cherry");

// 使用逗号作为分隔符,将列表中的字符串连接起来
String joinedString = String.join(",", fruits);

// 输出连接后的字符串
System.out.println(joinedString); // 输出:Apple,Banana,Cherry

大小写转换

  • toLowerCase()toUpperCase():分别用于将字符串中的字符转换为其小写或大写形式,并返回一个新的字符串。

    • 由于在Java中字符串是不可变的,所以这两个方法并不会修改原始字符串,而是创建一个新的字符串对象。

toLowerCase() 方法: 将字符串中的所有大写字母转换为相应的小写字母。

ini 复制代码
String str = "Hello, World!";
// 大写转小写
String lowerCaseStr = str.toLowerCase();
System.out.println(lowerCaseStr); // 输出:hello, world!

toUpperCase() 方法: 将字符串中的所有小写字母转换为对应的大写字母。

ini 复制代码
String str = "Hello, World!";
// 小写转大写
String upperCaseStr = str.toUpperCase();
System.out.println(upperCaseStr); // 输出:HELLO, WORLD!

其他操作

  • trim():删除字符串两端的空白字符(空格、制表符、换行符等)。这个方法不会改变原始字符串,而是返回一个新的字符串,该字符串是原始字符串经过修剪后的结果。
ini 复制代码
// 创建一个带有前后空白字符的字符串
String strWithSpaces = "   Hello, World!   ";

// 使用trim()方法去除前后空白
String trimmedStr = strWithSpaces.trim();

// 输出原始字符串和修剪后的字符串
System.out.println("原始字符串: " + strWithSpaces);
System.out.println("修改后的字符串: " + trimmedStr);
  • getBytes(String charsetName):将字符串转换为字节数组。

    • Java字符串内部采用Unicode编码存储,getBytes() 方法将这些Unicode字符转换为字节序列,具体使用的编码取决于方法的重载形式。

不带参数形式代码示例:

ini 复制代码
String str = "Hello, World!";
byte[] bytes = str.getBytes();
for (byte b : bytes) {
    System.out.print(Integer.toHexString(b & 0xFF) + " ");
}

带参数形式代码示例:

ini 复制代码
String str = "Hello, World!";
try {
    byte[] Bytes = str.getBytes("UTF-8");
    System.out.println(Arrays.toString(Bytes));
} catch (UnsupportedEncodingException e) {
    e.printStackTrace();
}
  • intern():将字符串加入到 JVM 的字符串常量池(String Pool)中,返回字符串在字符串池中的引用。

    • 字符串常量池是一个特殊的内存区域,用于存储唯一的字符串字面量和通过 intern() 方法加入的字符串对象引用。
    • 这样做的主要优点在于节省内存空间,特别是对于重复出现的字符串,可以确保在整个JVM中只有一个实例存在。

方法使用:

  • 当调用 intern() 方法时,如果常量池中已经有了一个与当前字符串内容相同的字符串,则该方法返回常量池中已有字符串的引用。
  • 如果常量池中没有相同内容的字符串,则将当前字符串添加到常量池,并返回常量池中新添加字符串的引用。

代码示例:

ini 复制代码
 // 创建两个内容相同的字符串
String str1 = new String("Java");
String str2 = "Java";

// 不调用intern()方法时,str1和str2指向不同的对象
System.out.println(str1 == str2); // 输出:false

// 调用intern()方法将str1加入常量池
str1 = str1.intern();

// 现在str1和str2指向常量池中同一个字符串对象
System.out.println(str1 == str2); // 输出:true

// 另一个示例,即使字符串是通过字符串拼接产生的
String str3 = new String("Ja") + new String("va");
str3 = str3.intern();
System.out.println(str3 == "Java"); // 输出:tru
相关推荐
坐吃山猪4 小时前
SpringBoot01-配置文件
java·开发语言
我叫汪枫4 小时前
《Java餐厅的待客之道:BIO, NIO, AIO三种服务模式的进化》
java·开发语言·nio
yaoxtao4 小时前
java.nio.file.InvalidPathException异常
java·linux·ubuntu
Swift社区5 小时前
从 JDK 1.8 切换到 JDK 21 时遇到 NoProviderFoundException 该如何解决?
java·开发语言
DKPT6 小时前
JVM中如何调优新生代和老生代?
java·jvm·笔记·学习·spring
phltxy6 小时前
JVM——Java虚拟机学习
java·jvm·学习
seabirdssss8 小时前
使用Spring Boot DevTools快速重启功能
java·spring boot·后端
喂完待续8 小时前
【序列晋升】29 Spring Cloud Task 微服务架构下的轻量级任务调度框架
java·spring·spring cloud·云原生·架构·big data·序列晋升
benben0448 小时前
ReAct模式解读
java·ai