字符串常用类
String 类及常用方法
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence,
Constable, ConstantDesc {
-
String 是一个final类,是 不可改变的字符序列。
-
字符串是常量,它在值创建之后就不能更改了。
-
String 对象的字符串内容是存储在一个字符数组value[]中的。
-
String 实现了Serializable: 表示String支持序列化的
实现了Comparable接口:表示String可以比较大小
-
String内部定义了 final char[] value 用于存储字符串数据
-
**String:**代表不可变的序列。
String s1 = "abc";
String s2 = "abc";
上面这种,对String对象赋值的方式,被称为字面量赋值。会将值存在方法区,并且方法区不会存储一样的内容。所以 s1 和 s2其实是指向同一地址。
**总:**对已有的字符串是无法修改的。
String对象创建
构造函数
构造器 | 功能 |
---|---|
String() | 创建了一个字符串大小为0的String对象 |
String(String s) | 创建一个长度与s相等的String对象,且复制内容 |
String(char[] a) | 相当于this.value = Arrays.copyOf(value, value.length) |
String(char[] a, int startIndex, int count) | 从数组a的下标为startIndex,往后选择count个赋值 |
String实例化方式
字面常量定义
String s1 = "Hello World!";
String s2 = "Hello World!";
- 这种定义方式称为 字面常量定义 ,此时 s3 和 s4 的数据 “Hello World!” 声明在 方法区 中的 字符串常量池 中。
通过 new + 构造器的方式
String s3 = new String("Hello World!");
String s4 = new String("Hello World!");
- 这种方式定义的字符串,s1 , s2在堆空间中。
通过 == 对比
比较 | 结果 |
---|---|
s1 == s2 | true |
s1 == s3 | false |
s1 == s4 | false |
s3 == s4 | false |
原因:在java中,对象间用 == 连接,实在比较,对象地址是否相同。
小问题
String s = new String("abc"); 这种方式创建的时候,在内存中创建了几个对象?
答:创建了两个对象。一个是堆空间中的new结构,另一个是char[] 对应常量池中的数据 “abc”。
String常用API
API | 功能 |
---|---|
int length() | 返回字符串长度 |
char charAt(int index) | 返回下标为index的字符 |
boolean isEmpty() | 判断字符串是否为空 |
String toLowerCase() | 将String中所有字符转换为小写 |
String toUpperCase() | 将String中所有字符转换为大写 |
String trim() | 返回字符串的副本,去掉字符串原来的头部和尾部的空白 |
boolean equals(Object obj) | 比较字符串内容是否相同 |
boolean equalsIgnoreCase(String anotherString) | 与equals类似,忽略大小写 |
String concat(String str) | 将指定字符串连接到此字符串结尾,相当一于 ”+“ |
int compareTo(String anotherString) | 比较两个字符串的大小 |
String substring(int beginIndex) | 返回一个新的字符串,它是此字符串从beginIndex开始到最后的一个子字符串 |
String substring(int beginIndex, int endIndex) | 返回一个新字符串,它是此字符串从beginIndex开始截取到endIndex(不包含)的一个子字符串 |
boolean endsWith(String suffix) | 测试此字符串是否以指定的后缀结束 |
boolean startsWith(String prefix) | 测试此字符串是否以指定的前缀开始 |
boolean startsWith(String prefix, int toffset) | 测试此字符串从指定索引开始的子字符串是否以指定前缀开始 |
boolean contains(CharSequence s) | 当前仅当此字符串包含指定的char值序列时,返回true |
int indexOf(String str) | 返回指定子字符串在此字符串中第一次出现处的索引,未找到返回-1 |
int indexOf(String str, int fromIndex) | 返回指定子字符串在此字符串中第一次出现处的索引,从指定位置fromeIndex开始,未找到返回-1 |
int lastIndexOf(String str) | 返回指定字符串在此字符串中最右边(尾部)出现处的索引,未找到返回-1 |
int lastIndexOf(String str, int fromIndex) | 返回指定字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索,未找到返回-1 |
String replace(char oldChar, char newChar) | 返回一个新的字符串,它是通过用newChar替换此字符串中出现的所有oldChar得到的 |
String replace(CharSequence target, CharSequence replacement) | 使用自定的字面值替换序列,替换此字符串所匹配字面值目标序列的子字符串 |
String replaceAll(String regex, String replacement) | 使用给定replacement替换此字符串匹配给定的正则表达式的子字符串 |
String replaceFirst(String regex, String replacement) | 使用给定的replacement替换此字符串匹配给定的正则表达式,的第一个子字符串 |
boolean matches(String regex) | 告知此字符串是否匹配给定的正则表达式 |
String[] split(String regex) | 根据给定正则表达式的匹配拆分此字符串 |
String[] split(String regex, int limit) | 根据匹配给定的正则表达式,来拆分此字符串,最多不超过limit个,如果超过了,剩下下的就方法到最后一个元素中。 |
public class StringTest {
public static void main(String[] args) {
String s1 = "Hello World !";
System.out.println(s1.length());// 返回字符串长度
System.out.println(s1.charAt(3));// 返回下标为3的字符
System.out.println(s1.isEmpty());// 判断字符串是否为空
System.out.println(s1.toLowerCase());// 返回一个全为小写的字符串
System.out.println(s1.toUpperCase());// 返回一个全为大写的字符串
System.out.println(s1.trim());// 返回去掉首尾空白的字符串
System.out.println(s1.equals("123"));//比较连个字符串值是否相等
System.out.println(s1.equalsIgnoreCase("hello world !"));// 忽略大小写比较字符串值是否相等
System.out.println(s1.concat("Come on!"));// 将Come on!连接在s1后面,并返回一个新的字符串
System.out.println(s1.compareTo("hello world !") > 0);// 将两字符相减, 比较大小
System.out.println(s1.substring(7));//重下标为7的字符开始截取字串并返回
System.out.println(s1.substring(0, 6));// 截取0-5的字符串并返回
String s = "Hello World";
System.out.println(s.replace('H', 'l'));
System.out.println(s.replace("He", "hhhh"));
s = "12asdfasd2131fasd2134asd";
System.out.println(s.replaceAll("\d+", ",").replaceAll("^,|,$", ""));// 将匹配的数字全部用替换为 逗号
s = "12335";
System.out.println(s.matches("\d+")); //匹配数字
// 匹配电话测试, 判断电话是否符合规定
s = "0059-1245262";
System.out.println(s.matches("0059-\d{1,6}"));
s = "123|21312|213|123";
String[] ss = s.split("\|");
for (String sss : ss) {
System.out.println(sss);
}
}
}
StringBuffer
线程安全的原因:它每个方法都加上了 synchronized。
- StringBuffer 可变的字符序列: 线程安全的,效率低,其方法都是线程安全的。底层用 char[]型数组
- 可变,是在原来基础上改变,不用像String的字面量赋值,重新声明内存区。
常用API
API | 功能 |
---|---|
append(xxx) | 用于字符串的拼接 |
delete(int start, int end) | 删除指定位置的内容 |
replace(int start, int end,String str) | 把[start, end]位置替换为str |
insert(int offset, xxx) | 在指定位置插入xxx |
reverse() | 把当前字符序列逆转 |
indexOf(String str) | 返回str字符串在此字符串第一次出现位置的下标,为找到返回-1 |
substring(int start, int end) | 返回String,[start, end],原来的StringBuffer不变 |
length() | 返回字符串长度 |
charAt(int n) | 返回下标为n的字符 |
setCharAt(int n, char ch) | 将下标为n的字符,改为ch |
public static void main(String[] args) {
StringBuffer s = new StringBuffer("123abc");
s.append(1);
s.append("1");
System.out.println(s);
s.delete(0, 3);
System.out.println(s);
s.replace(0, 3, "hello");
System.out.println(s);
System.out.println(s.reverse());
System.out.println(s.length());
String s2 = s.substring(1, 3);
System.out.println(s2);
}
StringBuilder
- 可变的字符序列:线程不安全的,效率高, 底层用 char[]型数组
常用API
API | 功能 |
---|---|
append(xxx) | 用于字符串的拼接 |
delete(int start, int end) | 删除指定位置的内容 |
replace(int start, int end,String str) | 把[start, end]位置替换为str |
insert(int offset, xxx) | 在指定位置插入xxx |
reverse() | 把当前字符序列逆转 |
indexOf(String str) | 返回str字符串在此字符串第一次出现位置的下标,为找到返回-1 |
substring(int start, int end) | 返回String,[start, end],原来的StringBuffer不变 |
length() | 返回字符串长度 |
charAt(int n) | 返回下标为n的字符 |
setCharAt(int n, char ch) | 将下标为n的字符,改为ch |
public static void main(String[] args) {
StringBuilder s = new StringBuilder("123abc");
s.append(1);
s.append("1");
System.out.println(s);
s.delete(0, 3);
System.out.println(s);
s.replace(0, 3, "hello");
System.out.println(s);
System.out.println(s.reverse());
System.out.println(s.length());
String s2 = s.substring(1, 3);
System.out.println(s2);
}