字符串的介绍
java.lang.String类,代表字符串,引用类型
Java 程序中的所有字符串字面量(如 “abc” )都作为此类的实例实现
每当对字符串进行拼接、截取、分解、替换等操作时,好像它们的内容发生了改变
字符串的不可变性,它们的值在创建之后不能更改,必然是创建了新的字符串对象
一、解释不可变性
String s = "hello"; s = s + " world";
这行代码会创建两个字符串对象:“hello”、“hello world”
s
最初引用 "hello"
,然后引用 "hello world"
,而原来的 "hello"
字符串对象仍然存在于内存中
虽然字符串的内容是不可变的,但字符串对象可以引用其他可变对象,如字符数组、StringBuilder对象
这些情况下,可以修改可变对象改变字符串对象所引用的内容,但这并不会改变原始的字符串对象本身
// 修改字符数组的内容不会改变字符串的内容
char[] charArray = {'H', 'e', 'l', 'l', 'o'};
String str1 = new String(charArray);
charArray[0] = 'W';
System.out.println("字符串是常量:" + str1); // Hello
// 修改StringBuilder的内容不会改变字符串的内容
StringBuilder builder = new StringBuilder("Hello");
String str2 = new String(builder);
builder.append(" World");
System.out.println("字符串是常量:" + str2); // Hello
二、不可变性好处
1、安全性:不可变性使得字符串作为参数传递时不会因外部修改而引发意外行为
2、节省空间:字符串常量池的存在使得相同的字符串字面量只存储一次,从而节省了内存空间
3、线程安全:由于字符串是不可变的,多个线程可以共享相同的字符串对象而无需担心数据一致性问题
三、底层字节数组
public final class String
// String类实现Serializable接口、Comparable接口、CharSequence接口
implements java.io.Serializable, Comparable<String>, CharSequence {
/**
* The value is used for character storage.
*
* @implNote This field is trusted by the VM, and is a subject to
* constant folding if String instance is constant. Overwriting this
* field after construction will cause problems.
*
* Additionally, it is marked with {@link Stable} to trust the contents
* of the array. No other facility in JDK provides this functionality (yet).
* {@link Stable} is safe here, because value is never null.
*/
@Stable
private final byte[] value; // String底层是字节数组,使用final修饰
四、特殊字符的处理
contains、replace 按照字符串字面量匹配
split、replaceAll、replaceFirst 按照正则表达式匹配
反斜线在字符串中用作转义字符,同时也是正则表达式的转义字符
// 八进制转义序列:\0-\377,1到3位八进制数
String s = "2\0\0\0023";
System.out.println(s); // 2NULNULSTX3
String s = "You\\You\\Yi";
String replace = s.replace("\\", "");
System.out.println(replace); // YouYouYi
String replaceAll = s.replaceAll("\\\\", "");
System.out.println(replaceAll); // YouYouYi
字符串的获取
-
public int length():获取字符串长度
-
public String concat(String str):拼接字符串,与
+
等效 -
public char charAt(int index):获取指定索引位置的字符
-
public int indexOf(String str):返回子串第一次出现的索引位置,没有则返回 -1
public int indexOf(String str, int fromIndex) fromIndex - 开始搜索的索引位置
-
public int lastIndexOf(String str):返回子串最后一次出现的索引位置,没有则返回 -1
public int lastIndexOf(String str, int fromIndex) fromIndex - 开始搜索的索引位置
String str = "hello";
System.out.println(str.length()); // 5
System.out.println(str.charAt(0)); // h
// 索引位置从零开始,前面有几个字符
System.out.println(str.indexOf("l")); // 2 前面有两个字符
System.out.println(str.indexOf("l", 3)); // 3 前面有三个字符
System.out.println(str.lastIndexOf("l")); // 3 前面有三个字符
System.out.println(str.indexOf("world")); // -1 参数字符串不存在
// 字符串是常量;它们的值在创建之后不能更改
String str1 = "abc";
String str2 = "def";
String str3 = str1.concat(str2);
System.out.println(str1); // abc
System.out.println(str2); // def
System.out.println(str3); // abcdef
String对象的字符序列中的转义字符是一个字符,\n
代表换行
字符序列中如果使用目录符,Windows目录符必须转义写成\\
,Unix目录符/
直接使用即可
String path = "E:\\JavaLearning\\Hello.java";
int indexOne = path.indexOf("\\"); // 2
int indexTwo = path.lastIndexOf("\\"); // 15
字符串的转换
-
public char[] toCharArray():将字符串转为字符数组(对字符串中的每个字符进行操作时)
-
public byte getBytes():将字符串转为字节数组(IO流操作时)
public byte[] getBytes(Charset charset)
public byte[] getBytes(String charsetName) throws UnsupportedEncodingException
-
public void getChars(int begin, int end, char[] c, int offset) 必须保证数组可以容纳被复制的字符
String str = "hello";
char[] chars = str.toCharArray();
byte[] bytes = str.getBytes();
System.out.println(chars); // hello
System.out.println(Arrays.toString(bytes)); // [104, 101, 108, 108, 111]
String string = "1931年9月18日-1945年9月2日,14年抗战胜利";
char[] array = new char[7];
string.getChars(21, 28, array, 0);
System.out.println(array); // 14年抗战胜利 21+7=28
其他常用方法
public String trim() // 移除前导空白和尾部空白
public String intern() // 字符串取自字符串常量池
public boolean matches(String regex) // 是否匹配给定的正则表达式
public boolean contains(CharSequence s) // 是否包含指定字符序列
public boolean startsWith(String prefix) // 是否以指定前缀开头
public boolean endsWith(String suffix) // 是否以指定后缀结尾
public String toUpperCase() // 所有字符转换为大写字母
public String toLowerCase() // 所有字符转换为小写字母
public static String copyValueOf(char[] data) // 返回字符数组表示的字符串
public static String copyValueOf(char[] data,
int offset,int count) // 从offset开始,count个字符
public int compareTo(String anotherString) // 按字典顺序比较两个字符串,区分大小写
public int compareToIgnoreCase(String str) // 按字典顺序比较两个字符串,忽略大小写
// delimiter - 分隔符 elements - 加入的元素
public static String join(CharSequence delimiter,CharSequence... elements)
public static String join(CharSequence delimiter,
Iterable<? extends CharSequence> elements)