Java String类

112 阅读9分钟

The String class represents character strings. All string literals in Java programs, such as "abc", are implemented as instances of this class.

Strings are constant; their values cannot be changed after they are created. String buffers support mutable strings. Because String objects are immutable they can be shared. For example:

String str = "abc";

is equivalent to:

char data[] = {'a', 'b', 'c'};
String str = new String(data);

字符串广泛应用在 Java 编程中,在 Java 中字符串属于对象,Java 提供了 String 类来创建和操作字符串。

字符串是一个字符序列,例如 “Hello” 是一个由 5 个字符组成的字符串。在 Java 中,字符串是一个不可变对象,这意味着它是常量,一旦创建就不能更改。如果需要对字符串做很多修改,那么应该选择使用 StringBuffer 或 StringBuilder 类。

一、创建字符串

Java 中有两种创建 String 的方法:

  • 字符串字面量。
  • 使用 new 关键字。

1、字符串字面量

在 Java 中,可以像这样创建字符串:将字符串文字分配给字符串实例:

String str1 = "欢迎"; 
String str2 = "欢迎"; 

这种方法的问题:正如开头所说,String 是 Java 中的一个对象。但是我们还没有使用上面的 new 关键字创建任何字符串对象。编译器为我们完成这项任务,它创建一个具有字符串文字的字符串对象(“欢迎”)并将其分配给提供的字符串实例。

但是如果对象已经存在于内存中,它不会创建新对象,而是将存在的旧对象分配给新实例,这意味着即使我们上面有两个字符串实例(str1 和 str2),编译器只在字符串对象上创建(“欢迎”)并将相同的值分配给两个实例。例如,有 10 个字符串实例具有相同的值,这意味着内存中只有一个对象具有该值,并且所有 10 个字符串实例都指向同一个对象。

如果您对上述这段话的内容不是很理解,可以先跳过,继续学习下面的内容,我们会在后续的章节中,进行详细的讲解。

如果我们想要两个不同的对象具有相同的字符串怎么办?为此,我们需要使用 new 关键字创建字符串。

2、使用 new 关键字

正如上面所说,当我们尝试将同一个字符串对象分配给两个不同的文字时,编译器只创建了一个对象,并使两个文字指向同一个对象。为了解决这个问题,我们可以创建这样的字符串:

String str1 = new String ( "欢迎" ); 
String str2 = new String ( "欢迎" );  

在这种情况下,编译器将在内存中创建两个具有相同字符串的不同对象。

String str1 = "欢迎"; 
String str2 = "欢迎";
System.out.println(str1 == str2); // true
str1 = "你好";
System.out.println(str2); // 欢迎
String str3 = new String ( "欢迎" ); 
String str4 = new String ( "欢迎" );
System.out.println(str3 == str4); //false
str3 = "你好";
System.out.println(str4); // 欢迎

二、常用的 String 方法

1、char charAt(int index)

它返回指定索引处的字符。指定的索引值应介于 0 到 length() -1 之间,包括两端值。如果 index < 0 或 index >= String.length() 的长度,它会抛出 IndexOutOfBoundsException

示例:

String str = "lintcode";
char ch = str.charAt(0);	// ch 的值为 l 

2、boolean equals(Object obj)

将字符串与指定的字符串进行比较,如果两者都匹配则返回 true,否则返回 false
示例:

String str1 = "lintcode";
String str2 = "lintcode";
boolean rs = str1.equals(str2);		// rs 的值为 true

3、boolean startsWith(String prefix)

它测试字符串是否具有指定的前缀,如果是,则返回 true 否则返回 false

示例:

String str = "lintcode";
boolean rs = str.startsWith("lint");	 // rs 的值为 true

4、boolean endsWith(String suffix)

检查字符串是否以指定的后缀结尾。

示例:

String str = "lintcode";
boolean rs = str.endsWith("code");	 // rs 的值为 true

5、int indexOf(String str)

此方法返回指定子字符串 str 第一次出现的索引。若 str 没有出现过,则返回值为 -1

示例:

String str = "lintcodecode";
int index = str.indexOf("co");		// index 的值为 4

6、int lastIndexOf(String str)

返回字符串 str 最后一次出现的索引。

示例:

String str = "lintcodecode";
int index = str.lastIndexOf("co");		// index 的值为 8

7、String substring(int beginIndex, int endIndex)

返回子字符串。子串以 beginIndex 处的字符开始,以 endIndex 处的字符结束。

If we don't specify endIndex, the method will return all the characters from beginIndex.

  • beginIndex - the beginning index, inclusive.

  • endIndex - the ending index, exclusive.

示例:

String str = "lintcode";
String s = str.substring(0,4);		// s 的值为 lint

8、String concat(String str)

在字符串的末尾连接指定的字符串 “str”。

示例:

String str1 = "hello ";
String str2 = "lintcode";
String t = str1 + str2;		// t 的值为 hello lintcode
String s = str1.concat(str2);		// s 的值为 hello lintcode

9、String replace(char oldChar, char newChar)

它在用 newChar 更改 oldChar 的所有出现后返回新的更新字符串。

示例:

String str = "clintcodec";
String s = str.replace('c','a');	// s 的值为 alintaodea

10、String toUpperCase()

将字符串转成全大写,等效于 toUpperCase(Locale.getDefault())

示例:

String str = "lintcode";
String s = str.toUpperCase();		// s 的值为 LINTCODE

11、String toLowerCase()

将字符串转成全小写,等效于 toLowerCase(Locale.getDefault())

示例:

String str = "LINTCODE";
String s = str.toLowerCase();		// s 的值为 lintcode

12、String[] split(String regex)

与 split(String regex, int limit) 方法相同,但它没有任何阈(yù)值(临界值)限制。

示例:

String str = "a&b&c&d";
String arr[] = str.split("&");		// arr 的值为 ["a", "b", "c", "d"]

13、String trim()

从原始字符串中省略前导和尾随空格后返回子字符串。

示例:

String str = " lintcode ";
String s = str.trim();			// s 的值为 lintcode

14、int length()

它返回字符串的长度。

示例:

String str = "lintcode";
int len = str.length();		// len 的值为 8

三、其他方法

  • boolean equalsIgnoreCase(String string):它的工作原理与 equals 方法相同,但在比较字符串时不考虑大小写。它进行不区分大小写的比较。
  • int compareTo(String string):此方法根据字符串中每个字符的 Unicode 值比较两个字符串。
  • int compareToIgnoreCase(String string):与 CompareTo 方法相同,但它在比较过程中忽略大小写。
  • boolean startsWith(String prefix, int offset):它检查子字符串(从指定的偏移索引开始)是否具有指定的前缀。
  • int hashCode():它返回字符串的哈希码。
System.out.println("AbC".equalsIgnoreCase("aBc")); // true
System.out.println("AbC".compareTo("aBc")); // 65 - 97 = -32
System.out.println("AbC".compareToIgnoreCase("aBc")); // 0
System.out.println("AbC".hashCode()); // 65 * 31^(3-1) + 98 * 31^(3-2) + 67 = 65570
  • int indexOf(int ch):返回指定字符 ch 在字符串中第一次出现的索引。
  • int indexOf(int ch, int fromIndex):与 indexOf 方法相同,但它从指定的 fromIndex 开始在字符串中搜索。
  • int lastIndexOf(int ch):它返回字符串中最后一次出现的字符 ch
  • int lastIndexOf(int ch, int fromIndex):与 lastIndexOf(int ch) 方法相同,它从 fromIndex 开始搜索。
  • String substring(int beginIndex):它返回字符串的子字符串。子字符串以指定索引处的字符开头。
  • boolean contains(CharSequence s):它检查字符串是否包含指定的字符值序列。如果是,则返回 true 否则返回 false。它抛出 NullPointerException of 's' is null
  • String toUpperCase(Locale locale):使用指定语言环境定义的规则将字符串转换为大写字符串。
  • public String intern():该方法在内存池中搜索指定的字符串,如果找到则返回它的引用,否则它将内存空间分配给指定的字符串并为其分配引用。
  • public boolean isEmpty():如果给定字符串的长度为 0,则此方法返回 true。如果指定的 Java 字符串的长度不为零,则返回 false
  • String[] split(String regex, int limit):它拆分字符串并返回与给定正则表达式匹配的子字符串数组。limit 是这里的结果阈值。
  • String toLowerCase(Locale locale):它使用给定语言环境定义的规则将字符串转换为小写字符串。
  • public static String format():这个方法返回一个格式化的 String
  • static String copyValueOf(char[] data):它返回一个包含指定字符数组字符的字符串。
  • static String copyValueOf(char[] data, int offset, int count):与上面的方法相同,但有两个额外的参数——子数组的初始偏移量和子数组的长度。
  • void getChars(int srcBegin, int srcEnd, char[] dest, int destBegin):将 src 数组的字符复制到 dest 数组。只有指定的范围被复制(srcBegin 到 srcEnd)到 dest 子数组(从 destBegin 开始)。
  • boolean contentEquals(StringBuffer sb):它将字符串与指定的字符串缓冲区进行比较。
  • boolean regionMatches(int srcoffset, String dest, int destoffset, int len):它将输入的子字符串与指定字符串的子字符串进行比较。
  • boolean regionMatches(boolean ignoreCase, int srcoffset, String dest, int destoffset, int len): regionMatches 方法的另一种变体,带有额外的布尔参数来指定比较是区分大小写还是不区分大小写。
  • byte[] getBytes(String charsetName):它使用指定的字符集编码将字符串转换为字节序列,并返回结果字节数组。
  • byte[] getBytes():此方法类似于上述方法,只是使用默认字符集编码将字符串转换为字节序列。
  • int codePointAt(int index):它类似于 charAt 方法,但它返回指定索引的 Unicode 代码点值而不是字符本身。
  • public static String join():此方法使用指定的分隔符连接给定的字符串并返回连接的 Java 字符串。
  • String replaceAll(String regex, String replacement):它将所有出现的符合正则表达式正则表达式的子字符串替换为替换字符串。
  • String replaceFirst(String regex, String replacement):它用指定的替换字符串替换第一个符合给定正则表达式 “regex” 的子字符串。
  • boolean matches(String regex):它检查字符串是否与指定的正则表达式 正则表达式匹配 。
  • static String valueOf():此方法返回传递参数的字符串表示形式,例如 intlongfloatdoublechar 和 char 数组。
  • char[] toCharArray():将字符串转换为字符数组。

四、StringBuilder 和 StringBuffer

当对字符串进行修改的时候,需要使用 StringBuffer 和 StringBuilder 类。

和 String 类不同的是,StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象。image.png

在使用 StringBuffer 类时,每次都会对 StringBuffer 对象本身进行操作,而不是生成新的对象,所以如果需要对字符串进行修改推荐使用 StringBuffer

StringBuilder 类在 Java 5 中被提出,它和 StringBuffer之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)。

由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。

实例

StringBuilder sb = new StringBuilder(10);
sb.append("Runoob..");
System.out.println(sb);
sb.append("!");
System.out.println(sb);
sb.insert(8, "Java");
System.out.println(sb);
sb.delete(5,8);
System.out.println(sb);

以上实例编译运行结果如下:

Runoob..
Runoob..!
Runoob..Java!
RunooJava!

然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。

示例:

StringBuffer sBuffer = new StringBuffer("LintCode算法官网:");
sBuffer.append("www");
sBuffer.append(".lintcode");
sBuffer.append(".com");
System.out.println(sBuffer);  

运行结果为:

LintCode算法官网:www.lintcode.com

StringBuffer 方法

以下是 StringBuffer 类支持的主要方法:

序号方法描述
1public StringBuffer append(String s) 将指定的字符串追加到此字符序列。
2public StringBuffer reverse() 将此字符序列用其反转形式取代。
3public delete(int start, int end) 移除此序列的子字符串中的字符。
4public insert(int offset, int i) 将 int 参数的字符串表示形式插入此序列中。
5insert(int offset, String str) 将 str 参数的字符串插入此序列中。
6replace(int start, int end, String str) 使用给定 String 中的字符替换此序列的子字符串中的字符。

转自:

docs.oracle.com/en/java/jav…

www.lintcode.com/learn/205/5…