Java 中文官方教程 2022 版(五)(3)https://developer.aliyun.com/article/1486296
将数字转换为字符串
有时您需要将数字转换为字符串,因为您需要在其字符串形式上进行操作。有几种简单的方法可以将数字转换为字符串:
int i; // Concatenate "i" with an empty string; conversion is handled for you. String s1 = "" + i;
或者
// The valueOf class method. String s2 = String.valueOf(i);
每个Number
子类都包括一个类方法toString()
,将其原始类型转换为字符串。例如:
int i; double d; String s3 = Integer.toString(i); String s4 = Double.toString(d);
ToStringDemo
示例使用toString
方法将数字转换为字符串。然后程序使用一些字符串方法来计算小数点前后的数字位数:
public class ToStringDemo { public static void main(String[] args) { double d = 858.48; String s = Double.toString(d); int dot = s.indexOf('.'); System.out.println(dot + " digits " + "before decimal point."); System.out.println( (s.length() - dot - 1) + " digits after decimal point."); } }
该程序的输出为:
3 digits before decimal point. 2 digits after decimal point.
操作字符串中的字符
原文:
docs.oracle.com/javase/tutorial/java/data/manipstrings.html
String
类有许多方法用于检查字符串的内容,在字符串中查找字符或子字符串,更改大小写以及其他任务。
通过索引获取字符和子字符串
您可以通过调用charAt()
访问器方法在字符串中获取特定索引处的字符。第一个字符的索引为 0,而最后一个字符的索引为length()-1
。例如,以下代码获取字符串中索引为 9 的字符:
String anotherPalindrome = "Niagara. O roar again!"; char aChar = anotherPalindrome.charAt(9);
索引从 0 开始,因此索引为 9 的字符是’O’,如下图所示:
如果要从字符串中获取多个连续字符,可以使用substring
方法。substring
方法有两个版本,如下表所示:
String
类中的substring
方法
方法 | 描述 |
String substring(int beginIndex, int endIndex) |
返回一个新的字符串,该字符串是此字符串的子字符串。子字符串从指定的beginIndex 开始,延伸到索引endIndex - 1 的字符。 |
String substring(int beginIndex) |
返回一个新的字符串,该字符串是此字符串的子字符串。整数参数指定第一个字符的索引。在这里,返回的子字符串延伸到原始字符串的末尾。 |
以下代码从尼亚加拉回文中获取从索引 11 到索引 15 之前的子字符串,即单词"roar":
String anotherPalindrome = "Niagara. O roar again!"; String roar = anotherPalindrome.substring(11, 15);
用于操作字符串的其他方法
以下是用于操作字符串的几种其他String
方法:
String
类中用于操作字符串的其他方法
方法 | 描述 |
String[] split(String regex) String[] split(String regex, int limit) |
搜索由字符串参数指定的匹配项(其中包含正则表达式)并相应地将此字符串拆分为字符串数组。可选的整数参数指定返回数组的最大大小。正则表达式在标题为"正则表达式"的课程中介绍。 |
CharSequence subSequence(int beginIndex, int endIndex) |
返回从beginIndex 索引开始直到endIndex - 1 的新字符序列。 |
String trim() |
返回删除前导和尾随空格的此字符串的副本。 |
String toLowerCase() String toUpperCase() |
返回转换为小写或大写的此字符串的副本。如果不需要转换,则这些方法返回原始字符串。 |
在字符串中搜索字符和子字符串
以下是一些用于在字符串中查找字符或子字符串的其他String
方法。String
类提供了返回特定字符或子字符串在字符串中位置的访问方法:indexOf()
和lastIndexOf()
。indexOf()
方法从字符串的开头向前搜索,而lastIndexOf()
方法从字符串的末尾向后搜索。如果未找到字符或子字符串,indexOf()
和lastIndexOf()
将返回-1。
String
类还提供了一个搜索方法contains
,如果字符串包含特定的字符序列,则返回 true。当您只需要知道字符串包含一个字符序列,但精确位置并不重要时,请使用此方法。
以下表格描述了各种字符串搜索方法。
String
类中的搜索方法
方法 | 描述 |
int indexOf(int ch) int lastIndexOf(int ch) |
返回指定字符的第一个(最后一个)出现的索引。 |
int indexOf(int ch, int fromIndex) int lastIndexOf(int ch, int fromIndex) |
返回指定字符的第一个(最后一个)出现的索引,从指定索引向前(向后)搜索。 |
int indexOf(String str) int lastIndexOf(String str) |
返回指定子字符串的第一个(最后一个)出现的索引。 |
int indexOf(String str, int fromIndex) int lastIndexOf(String str, int fromIndex) |
返回指定子字符串的第一个(最后一个)出现的索引,从指定索引向前(向后)搜索。 |
boolean contains(CharSequence s) |
如果字符串包含指定的字符序列,则返回 true。 |
注意: CharSequence
是一个由String
类实现的接口。因此,您可以将字符串作为contains()
方法的参数。
将字符和子字符串替换为字符串
String
类几乎没有用于在字符串中插入字符或子字符串的方法。一般情况下,这些方法是不需要的:您可以通过将您从字符串中删除的子字符串与您要插入的子字符串连接起来创建一个新的字符串。
String
类确实有四种用于替换找到的字符或子字符串的方法。它们是:
String
类中用于操作字符串的方法
方法 | 描述 |
String replace(char oldChar, char newChar) |
返回一个新字符串,该字符串由将此字符串中所有旧字符的出现替换为新字符而生成。 |
String replace(CharSequence target, CharSequence replacement) |
用指定的替换序列替换此字符串中与字面目标序列匹配的每个子字符串。 |
String replaceAll(String regex, String replacement) |
用给定替换替换此字符串中与给定正则表达式匹配的每个子字符串。 |
String replaceFirst(String regex, String replacement) |
用给定的替换字符串替换与给定正则表达式匹配的此字符串的第一个子字符串。 |
一个示例
以下类,Filename
,演示了使用lastIndexOf()
和substring()
来分离文件名的不同部分。
**注意:**以下Filename
类中的方法没有进行任何错误检查,并假定它们的参数包含完整的目录路径和带有扩展名的文件名。如果这些方法是生产代码,它们将验证它们的参数是否正确构造。
public class Filename { private String fullPath; private char pathSeparator, extensionSeparator; public Filename(String str, char sep, char ext) { fullPath = str; pathSeparator = sep; extensionSeparator = ext; } public String extension() { int dot = fullPath.lastIndexOf(extensionSeparator); return fullPath.substring(dot + 1); } // gets filename without extension public String filename() { int dot = fullPath.lastIndexOf(extensionSeparator); int sep = fullPath.lastIndexOf(pathSeparator); return fullPath.substring(sep + 1, dot); } public String path() { int sep = fullPath.lastIndexOf(pathSeparator); return fullPath.substring(0, sep); } }
这里有一个程序,FilenameDemo
,它构造了一个Filename
对象并调用了它的所有方法:
public class FilenameDemo { public static void main(String[] args) { final String FPATH = "/home/user/index.html"; Filename myHomePage = new Filename(FPATH, '/', '.'); System.out.println("Extension = " + myHomePage.extension()); System.out.println("Filename = " + myHomePage.filename()); System.out.println("Path = " + myHomePage.path()); } }
以下是程序的输出:
Extension = html Filename = index Path = /home/user
如下图所示,我们的extension
方法使用lastIndexOf
来定位文件名中句点(.)的最后一个出现位置。然后substring
使用lastIndexOf
的返回值来提取文件名扩展名,即从句点到字符串末尾的子字符串。此代码假定文件名中有一个句点;如果文件名中没有句点,lastIndexOf
将返回-1,而substring
方法将抛出StringIndexOutOfBoundsException
。
还要注意,extension
方法使用dot + 1
作为substring
的参数。如果句点字符(.)是字符串的最后一个字符,则dot + 1
等于字符串的长度,这比字符串的最大索引大 1(因为索引从 0 开始)。这是substring
的合法参数,因为该方法接受一个等于但不大于字符串长度的索引,并将其解释为“字符串的结尾”。
比较字符串和字符串部分
原文:
docs.oracle.com/javase/tutorial/java/data/comparestrings.html
String
类有许多用于比较字符串和字符串部分的方法。以下表格列出了这些方法。
比较字符串的方法
方法 | 描述 |
boolean endsWith(String suffix) boolean startsWith(String prefix) |
如果此字符串以指定为方法参数的子字符串结尾或以其开头,则返回true 。 |
boolean startsWith(String prefix, int offset) |
考虑从索引offset 开始的字符串,并返回如果以指定为参数的子字符串开头则返回true 。 |
int compareTo(String anotherString) |
按字典顺序比较两个字符串。返回一个整数,指示此字符串是否大于(结果为> 0)、等于(结果为= 0)或小于(结果为< 0)参数。 |
int compareToIgnoreCase(String str) |
按字典顺序比较两个字符串,忽略大小写差异。返回一个整数,指示此字符串是否大于(结果为> 0)、等于(结果为= 0)或小于(结果为< 0)参数。 |
boolean equals(Object anObject) |
如果参数是表示与此对象相同字符序列的String 对象,则返回true 。 |
boolean equalsIgnoreCase(String anotherString) |
如果参数是表示与此对象相同字符序列的String 对象,则返回true ,忽略大小写差异。 |
boolean regionMatches(int toffset, String other, int ooffset, int len) |
测试此字符串的指定区域是否与 String 参数的指定区域匹配。区域长度为len ,从此字符串的索引toffset 和另一个字符串的索引ooffset 开始。 |
boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len) |
测试此字符串的指定区域是否与 String 参数的指定区域匹配。区域长度为len ,从此字符串的索引toffset 和另一个字符串的索引ooffset 开始。布尔参数指示是否应忽略大小写;如果为 true,则在比较字符时忽略大小写。 |
boolean matches(String regex) |
测试此字符串是否与指定的正则表达式匹配。正则表达式在标题为“正则表达式”的课程中讨论。 |
以下程序RegionMatchesDemo
使用regionMatches
方法在另一个字符串中搜索字符串:
public class RegionMatchesDemo { public static void main(String[] args) { String searchMe = "Green Eggs and Ham"; String findMe = "Eggs"; int searchMeLength = searchMe.length(); int findMeLength = findMe.length(); boolean foundIt = false; for (int i = 0; i <= (searchMeLength - findMeLength); i++) { if (searchMe.regionMatches(i, findMe, 0, findMeLength)) { foundIt = true; System.out.println(searchMe.substring(i, i + findMeLength)); break; } } if (!foundIt) System.out.println("No match found."); } }
此程序的输出为Eggs
。
该程序逐个字符遍历searchMe
引用的字符串。对于每个字符,程序调用regionMatches
方法来确定从当前字符开始的子字符串是否与程序正在查找的字符串匹配。
StringBuilder 类
StringBuilder
对象类似于 String
对象,不同之处在于它们可以被修改。在内部,这些对象被视为包含一系列字符的可变长度数组。在任何时候,通过方法调用可以更改序列的长度和内容。
除非字符串生成器在代码更简单(请参见本节末尾的示例程序)或性能更好方面提供优势,否则应始终使用字符串。例如,如果需要连接大量字符串,则追加到StringBuilder
对象更有效率。
长度和容量
StringBuilder
类,类似于 String
类,具有返回生成器中字符序列长度的 length()
方法。
与字符串不同,每个字符串生成器还有一个容量,即已分配的字符空间数。容量由 capacity()
方法返回,始终大于或等于长度(通常大于),并且会根据需要自动扩展以容纳对字符串生成器的添加。
StringBuilder
构造函数
构造函数 | 描述 |
StringBuilder() |
创建一个容量为 16(16 个空元素)的空字符串生成器。 |
StringBuilder(CharSequence cs) |
构造一个包含与指定 CharSequence 相同字符的字符串生成器,CharSequence 后面还有额外的 16 个空元素。 |
StringBuilder(int initCapacity) |
创建一个具有指定初始容量的空字符串生成器。 |
StringBuilder(String s) |
创建一个字符串生成器,其值由指定的字符串初始化,字符串后面还有额外的 16 个空元素。 |
例如,以下代码
// creates empty builder, capacity 16 StringBuilder sb = new StringBuilder(); // adds 9 character string at beginning sb.append("Greetings");
会生成一个长度为 9,容量为 16 的字符串生成器:
StringBuilder
类有一些与长度和容量相关的方法,而 String
类没有:
长度和容量方法
方法 | 描述 |
void setLength(int newLength) |
设置字符序列的长度。如果newLength 小于length() ,则字符序列中的最后字符将被截断。如果newLength 大于length() ,则在字符序列的末尾添加空字符。 |
void ensureCapacity(int minCapacity) |
确保容量至少等于指定的最小值。 |
一些操作(例如,append()
,insert()
或setLength()
)可以增加字符串构建器中字符序列的长度,使得结果的length()
大于当前的capacity()
。当这种情况发生时,容量会自动增加。
StringBuilder 操作
StringBuilder
上的主要操作,这些操作在String
中不可用,是append()
和insert()
方法,这些方法被重载以接受任何类型的数据。每个方法将其参数转换为字符串,然后将该字符串的字符附加或插入到字符串构建器中的字符序列中。append
方法总是在现有字符序列的末尾添加这些字符,而insert
方法在指定点添加字符。
这里是StringBuilder
类的一些方法。
各种StringBuilder
方法
方法 | 描述 |
| `StringBuilder append(boolean b) StringBuilder append(char c)
StringBuilder append(char[] str)
StringBuilder append(char[] str, int offset, int len)
StringBuilder append(double d)
StringBuilder append(float f)
StringBuilder append(int i)
StringBuilder append(long lng)
StringBuilder append(Object obj)
StringBuilder append(String s)` | 将参数附加到此字符串构建器。在附加操作发生之前,数据将被转换为字符串。 |
StringBuilder delete(int start, int end) StringBuilder deleteCharAt(int index) |
第一个方法删除StringBuilder 的字符序列中从start 到end-1 (包括end-1 )的子序列。第二个方法删除位于index 处的字符。 |
| `StringBuilder insert(int offset, boolean b) StringBuilder insert(int offset, char c)
StringBuilder insert(int offset, char[] str)
StringBuilder insert(int index, char[] str, int offset, int len)
StringBuilder insert(int offset, double d)
StringBuilder insert(int offset, float f)
StringBuilder insert(int offset, int i)
StringBuilder insert(int offset, long lng)
StringBuilder insert(int offset, Object obj)
StringBuilder insert(int offset, String s)` | 将第二个参数插入到字符串构建器中。第一个整数参数表示要插入数据之前的索引。在插入操作发生之前,数据将被转换为字符串。 |
StringBuilder replace(int start, int end, String s) void setCharAt(int index, char c) |
替换此字符串构建器中指定的字符。 |
StringBuilder reverse() |
反转此字符串构建器中的字符序列。 |
String toString() |
返回一个包含构建器中字符序列的字符串。 |
注意: 您可以通过首先使用StringBuilder
类的toString()
方法将字符串构建器转换为字符串,然后使用StringBuilder(String str)
构造函数将字符串转换回字符串构建器,从而在StringBuilder
对象上使用任何String
方法。
一个示例
在标题为“字符串”的部分列出的StringDemo
程序是一个例子,如果使用StringBuilder
而不是String
会更有效率。
StringDemo
反转了一个回文。这里再次列出它的代码:
public class StringDemo { public static void main(String[] args) { String palindrome = "Dot saw I was Tod"; int len = palindrome.length(); char[] tempCharArray = new char[len]; char[] charArray = new char[len]; // put original string in an // array of chars for (int i = 0; i < len; i++) { tempCharArray[i] = palindrome.charAt(i); } // reverse array of chars for (int j = 0; j < len; j++) { charArray[j] = tempCharArray[len - 1 - j]; } String reversePalindrome = new String(charArray); System.out.println(reversePalindrome); } }
运行程序会产生这个输出:
doT saw I was toD
为了实现字符串反转,程序将字符串转换为字符数组(第一个for
循环),将数组反转为第二个数组(第二个for
循环),然后再转换回字符串。
如果你将palindrome
字符串转换为一个字符串生成器,你可以使用StringBuilder
类中的reverse()
方法。这样代码会更简单,更易于阅读:
public class StringBuilderDemo { public static void main(String[] args) { String palindrome = "Dot saw I was Tod"; StringBuilder sb = new StringBuilder(palindrome); sb.reverse(); // reverse it System.out.println(sb); } }
运行这个程序会产生相同的输出:
doT saw I was toD
注意,println()
打印一个字符串生成器,如下所示:
System.out.println(sb);
因为sb.toString()
会被隐式调用,就像在println()
调用中对任何其他对象一样。
注意: 还有一个StringBuffer
类,与StringBuilder
类完全相同,唯一的区别是它的方法是同步的,因此是线程安全的。线程将在并发课程中讨论。