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
相关推荐
xlsw_1 小时前
java全栈day20--Web后端实战(Mybatis基础2)
java·开发语言·mybatis
神仙别闹2 小时前
基于java的改良版超级玛丽小游戏
java
黄油饼卷咖喱鸡就味增汤拌孜然羊肉炒饭2 小时前
SpringBoot如何实现缓存预热?
java·spring boot·spring·缓存·程序员
暮湫2 小时前
泛型(2)
java
超爱吃士力架2 小时前
邀请逻辑
java·linux·后端
南宫生2 小时前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
转码的小石3 小时前
12/21java基础
java
李小白663 小时前
Spring MVC(上)
java·spring·mvc
GoodStudyAndDayDayUp3 小时前
IDEA能够从mapper跳转到xml的插件
xml·java·intellij-idea
装不满的克莱因瓶3 小时前
【Redis经典面试题六】Redis的持久化机制是怎样的?
java·数据库·redis·持久化·aof·rdb