介绍
String
是最广泛使用的Java类之一。本文提供了关于String
的一些实践问题和答案,以帮助您为面试做准备。
您还可以尝试Java String测验来测试您对String
类的了解。
String
类在Java中是什么?String
是一种数据类型吗?
String
是Java中的一个类,定义在java.lang
包中。它不像int
和long
那样是原始数据类型。String
类表示字符字符串。在几乎所有的Java应用程序中都使用String
。String
在Java中是不可变的和最终的,JVM使用字符串池来存储所有的String
对象。您可以使用双引号实例化String
对象,并且您可以重载+
运算符进行连接。
在Java中有哪些不同的方法可以创建一个String
对象?
您可以使用new
运算符创建一个String
对象,也可以使用双引号来创建一个String
对象。例如:
String str = new String("abc");
String str1 = "abc";
String
类中有几个构造函数可用于从char数组
、byte数组
、StringBuffer
和StringBuilder
获取String
。
当您使用双引号创建一个String
时,JVM会在字符串池中查找是否已存储了具有相同值的其他String
。如果字符串已经存储在池中,JVM将返回对该String
对象的引用。如果新的String
不在池中,JVM将创建一个具有给定值的新String
对象,并将其存储在字符串池中。当您使用new
运算符时,JVM会创建String
对象,但不会将其存储在字符串池中。您可以使用intern()
方法将String
对象存储在字符串池中,或者如果池中已存在具有相等值的String
,则返回对应的引用。
编写一个 Java 方法来检查输入的字符串是否为回文。
A string is a palindrome if its value is the same when reversed. For example, aba
is a palindrome string. The String
class doesn’t provide any method to reverse the string but the StringBuffer
and StringBuilder
classes have a reverse()
method that you can use to check whether a string is a palindrome. For example:
private static boolean isPalindrome(String str) {
if (str == null)
return false;
StringBuilder strBuilder = new StringBuilder(str);
strBuilder.reverse();
return strBuilder.toString().equals(str);
}
有时面试官可能要求你不使用任何其他类来检查一个回文。在这种情况下,你可以比较字符串两端的字符来判断它是否是一个回文。例如:
private static boolean isPalindromeString(String str) {
if (str == null)
return false;
int length = str.length();
System.out.println(length / 2);
for (int i = 0; i < length / 2; i++) {
if (str.charAt(i) != str.charAt(length - i - 1))
return false;
}
return true;
}
编写一个 Java 方法,从一个字符串对象中移除给定的字符。
我们可以使用 replaceAll
方法来将一个字符串中所有出现的字符替换为另一个字符串。需要注意的重点是 replaceAll()
接受 String
作为参数,所以你可以使用 Character
类来创建一个字符串,并将其用于替换所有字符为空字符串。
private static String removeChar(String str, char c) {
if (str == null)
return null;
return str.replaceAll(Character.toString(c), "");
}
如何在 Java 中将一个 String
转换为大写或小写?
你可以使用String
类的toUpperCase
和toLowerCase
方法将String
对象转换为全大写或全小写。这些方法有一个变体,接受一个Locale
参数,并使用给定语言环境的规则将字符串转换为大写或小写。
String subSequence
方法是什么?
Java 1.4引入了CharSequence
接口,String
类实现了这个接口,这就是为什么String
类有subSequence
方法的原因。在内部,subSequence
方法调用String substring
方法。
在Java程序中如何比较两个字符串?
Java `String
` 实现了 Comparable
接口,该接口有两种 compareTo()
方法的变体。 compareTo(String anotherString)
方法按字典顺序比较传递的参数与字符串对象。如果字符串对象在参数之前,则返回负整数;如果字符串对象在参数之后,则返回正整数。当两个字符串对象具有相同值时返回零。在这种情况下,equals(String str)
方法也返回 true
。 compareToIgnoreCase(String str)
方法与第一个方法类似,只是它忽略了大小写。它使用 Comparator
与 CASE_INSENSITIVE_ORDER
进行不区分大小写的比较。如果值为零,则 equalsIgnoreCase(String str)
也将返回 true。
如何在Java中将一个 String
转换为字符数组?
A String
object is a sequence of characters, so you can’t convert it to a single character. You can use use the charAt
method to get the character at given index or you can use the toCharArray()
method to convert a string to character array. Learn more about converting a string to a character array.
如何在Java中将一个 String
转换为字节数组?
你可以使用getBytes()
方法将String
对象转换为字节数组,你也可以使用构造函数new String(byte[] arr)
将字节数组转换为String
对象。了解更多关于将字符串转换为字节数组。
在Java中可以在switch case中使用String
吗?
Java 7扩展了对String
的switch case能力;早期的Java版本不支持此功能。如果你正在为字符串实现条件流程,你可以使用if-else条件,如果你使用的是Java 7或更高版本,你可以使用switch case。了解更多关于Java switch case string。
编写一个Java程序来打印字符串的所有排列。
你需要使用递归来找到一个字符串的所有排列。例如,AAB
的排列是 AAB
、ABA
和 BAA
。你还需要使用Set
来确保没有重复的值。了解更多关于查找字符串的所有排列。
编写一个Java函数来找到给定字符串中最长的回文串。
A string can contain palindrome substrings within it. Learn more about how to find the longest palindrome substring in a string.
在Java中,String
、StringBuffer
和StringBuilder
之间有什么区别?
A String
object is immutable and final in Java, so whenever you manipulate a String
object, it creates a new String
object. String manipulations are resource consuming, so Java provides two utility classes for string manipulations, StringBuffer
and StringBuilder
.
StringBuffer
和 StringBuilder
是可变类。 StringBuffer
操作是线程安全的和同步的,而 StringBuilder
操作则不是线程安全的。您应该在多线程环境中使用 StringBuffer
,在单线程环境中使用 StringBuilder
。由于没有同步的开销,StringBuilder
的性能比 StringBuffer
更快。
了解更多关于 String
、StringBuffer
和 StringBuilder
之间的区别 以及 StringBuffer
和 StringBuilder
的基准测试。
为什么在 Java 中 String
是不可变的?
String
在 Java 中是不可变的,因为这带来了几个好处:
- 由于在 Java 中
String
是不可变的,因此字符串池是可能的。 - 它增加了安全性,因为任何黑客都无法更改其值,它用于存储诸如数据库用户名或密码之类的敏感信息。
- 由于
String
是不可变的,所以在多线程中使用是安全的,并且不需要任何同步。 - 字符串在Java类加载器中被用到,不可变性确保由
ClassLoader
类加载了正确的类。
了解更多关于为什么在Java中String
是不可变的。
在Java中如何拆分字符串?
您可以使用split(String regex)
根据提供的正则表达式将String
拆分成String
数组。
为什么在Java中用字符数组而不是String
存储密码?
A String
object is immutable in Java and is stored in the string pool. Once it’s created it stays in the pool until garbage collection completes, so even though you’re done with the password it’s available in memory for longer duration. It’s a security risk because anyone having access to memory dump can find the password as clear text. If you use a character array to store password, you can set it to blank once you’re done with it. You can control for how long it’s available in memory and that avoids the security threat.
在Java中如何检查两个字符串是否相等?
有两种方法可以检查两个字符串是否相等。您可以使用==
运算符或equals()
方法。当您使用==
运算符时,它会检查String
的值以及对象引用。通常在Java编程中,您只想检查String
值是否相等。在这种情况下,您应该使用equals()
方法来检查两个Strings
是否相等。还有另一个函数叫做equalsIgnoreCase
,您可以使用它来忽略大小写。
String s1 = "abc";
String s2 = "abc";
String s3 = new String("abc");
System.out.println("s1 == s2 ? " + (s1 == s2)); //true
System.out.println("s1 == s3 ? " + (s1 == s3)); //false
System.out.println("s1 equals s3 ? " + (s1.equals(s3))); //true
Java中的字符串池是什么?
字符串池是存储在Java堆内存中的一组String
对象。String
是Java中的特殊类,您可以使用new
运算符创建一个String
对象,也可以通过在双引号中提供值来创建。了解更多关于Java字符串池的信息。
Java的String intern()
方法是做什么的?
当调用intern()
方法时,如果字符串池已经包含一个与此String
对象相等的String
(由equals(Object)
方法确定),则返回池中的字符串。否则,将此String
对象添加到池中,并返回对此String
对象的引用。该方法始终返回一个具有与此String
相同内容的String
对象,但保证来自唯一字符串池。
String
在Java中是线程安全的吗?
A String
object is immutable, so you can’t change its value after creation. This makes the String
object thread-safe and so it can be safely used in a multi-threaded environment. Learn more about thread Safety in Java.
String
为什么在Java中是常用的HashMap
键?
由于`String`对象是不可变的,所以在创建时会缓存其哈希码,不需要再次计算。这使得它成为映射中的键的绝佳选择,因为其处理速度比其他`HashMap`键对象快。
猜测输出
通过猜测以下Java代码片段的输出来测试自己。
public class StringTest {
public static void main(String[] args) {
String s1 = new String("digitalocean");
String s2 = new String("DIGITALOCEAN");
System.out.println(s1 = s2);
}
}
Output
DIGITALOCEAN
输出是`DIGITALOCEAN`,因为代码将`String s2`的值赋给了`String s1`。`=`是一个赋值运算符,将`y`的值赋给`x`的格式为`(x = y)`。`==`是一个比较运算符,用于检查两个字符串的引用对象是否相同。
public class Test {
public void foo(String s) {
System.out.println("String");
}
public void foo(StringBuffer sb) {
System.out.println("StringBuffer");
}
public static void main(String[] args) {
new Test().foo(null);
}
}
Output
Test.java:12: error: reference to foo is ambiguous
new Test().foo(null);
^
both method foo(String) in Test and method foo(StringBuffer) in Test match
此代码导致编译时错误,因为两个`foo`方法具有相同的名称,并且在`main`中对`foo`方法的调用传递了`null`。编译器不知道调用哪个方法。您还可以参考方法X对类型Y模糊不清的错误。
String s1 = new String("abc");
String s2 = new String("abc");
System.out.println(s1 == s2);
Output
false
输出为false
,因为该代码使用new
运算符创建String
对象,因此它在堆内存中创建,并且s1
和s2
将具有不同的引用。如果仅使用双引号创建字符串,则它们将位于字符串池中,并且将打印true
。
String s1 = "abc";
StringBuffer s2 = new StringBuffer(s1);
System.out.println(s1.equals(s2));
Output
false
输出为false
,因为s2
不是String
类型。String
类中的equals()
方法实现使用instanceof
运算符检查传递的对象类型是否为String
,如果对象不是String
,则返回false。
String s1 = "abc";
String s2 = new String("abc");
s2.intern();
System.out.println(s1 == s2);
Output
false
输出为false
。intern()
方法从字符串池中返回String
对象引用。但是,代码没有将其重新分配给s2
,因此s1
和s2
具有不同的对象引用。如果将第3行的代码更改为s2 = s2.intern();
,则输出将为true
。
以下代码创建了多少个String
对象?
String s1 = new String("Hello");
String s2 = new String("Hello");
Answer
答案是三。第1行的代码创建了一个在字符串池中具有值“Hello”的String
对象(第一个对象),然后在堆内存中创建了一个新的具有值“Hello”的String
对象(第二个对象)。第2行的代码创建了一个在堆内存中具有值“Hello”的新String
对象(第三个对象),并重用了字符串池中的Hello
字符串。
结论
在本文中,您回顾了一些关于String
的Java面试问题。
推荐阅读:
Source:
https://www.digitalocean.com/community/tutorials/java-string-interview-questions-and-answers