目录标题
String类的常用方法
字符串的构造
public class Test {
public static void main(String[] args) {
//使用常量串构造
String s1 = "hello world1";
System.out.println(s1);
//直接newString对象
String s2 = new String("hello world12");
System.out.println(s2);
//使用字符数组进行构造
char[] array = {'h','e','l','l','o',' ','w','o','r','l','d'};
String s3 = new String(array);
System.out.println(s3);
}
}
- String是引用类型,内部并不存储字符串本身,在String类的实现源码中,String类实例变量如下:
- 在Java当中使用""引起来的也是String类型对象
public class Test {
public static void main(String[] args) {
//s1和s2引用的是不同对象 s1和s3引用的是同一对象
String s1 = new String("hello");
String s2 = new String("world");
String s3 = s1;
String s4 = "";//s4指向的对象没有任何数据
String s5 = null;//s5不指向任何对象
System.out.println(s1.length());//获取字符串长度 - 5
System.out.println(s4.isEmpty());//如果字符串长度为0,返回ture,否则返回false
}
}
String对象的比较
- ==比较的是否引用同一个对象
对于内置类型, == 比较的变量中的值是否相同,对于引用类型,== 比较的是引用的地址是否相同。
public class Main {
public static void main(String[] args) {
String str1 = new String("hello");
String str2 = new String("hello");
System.out.println(str1 == str2);//比较值是否一样
System.out.println(str1.equals(str2));//String类型重写了equals方法
}
}
- boolean equals(Object anObject)方法
String类型重写了父类的Object中的equals方法,Object中的equals默认是==比较(比较的是对象的引用地址),而重写后的equals方法比较的是字符序列,而不是内存地址
public boolean equals(Object anObject) {
//检测this和anObject指向的是否是同一个对象
if (this == anObject) {
return true;
}
//检测anObject是否为String类型的对象
if (anObject instanceof String) {
//anObject向下转型为String类型对象
String anotherString = (String)anObject;
int n = value.length;
//this和anObject字符串长度是否相同
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
//从后往前逐个字符比较
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
public static void main(String[] args) {
String s1 = new String("hello");
String s2 = new String("hello");
String s3 = new String("world");
String s4 = "abcd";//s4和s5是字符串常量,指向的同一个对象
String s5 = "abcd";
System.out.println(s1 == s2);//false s1,s2,s3引用不同的对象
System.out.println(s1 == s3);//false
System.out.println(s1.equals(s2));//true 对象中的字符一样
System.out.println(s1.equals(s3));//false
System.out.println(s4 == s5);//true
}
- int compareTo(Strings) 方法
与equals比较不同的是,equals返回的是Boolean类型,compareTo返回的是int类型 比较方式为:
3.1 按照字符大小比较,如果出现不等的字符,返回两个字符的大小差值
3.2 如果前n个字符串相同(n为字符串长度最小值),返回两个字符串差值长度
3.3 如果两个字符串完全相同返回0
// int compareToIgnoreCase(String str) 方法
public static void main(String[] args) {
String s1 = new String("abc");
String s4 = new String("ac");
String s5 = new String("ABc");
String s2 = new String("abc");
String s3 = new String("abcde");
System.out.println(s1.compareTo(s4));//输出字符串差值
System.out.println(s1.compareToIgnoreCase(s5));//0
System.out.println(s1.compareTo(s2));//字符串相同
System.out.println(s1.compareTo(s3));//前n字符串相同,返回差值
}
字符串常用的操作方法
字符串查找方法
方法 | 功能 |
---|---|
char charAt(int index | 返回index位置上字符,如果index为负数或者越界,抛出IndexOutOfBoundsException异常 |
int indexOf(int ch) | 返回ch第一次出现的位置,没有返回-1 |
int indexOf(int ch, int fromIndex) | 从fromIndex位置开始找ch第一次出现的位置,没有返回-1 |
int indexOf(String str) | 返回str第一次出现的位置,没有返回-1 |
int indexOf(String str, intfromIndex | 从fromIndex位置开始找str第一次出现的位置,没有返回-1 |
从fromIndex位置开始找str第一次出现的位置,没有返回-1 | 从fromIndex位置开始找str第一次出现的位置,没有返回-1 |
int lastIndexOf(int ch, intfromIndex) | 从fromIndex位置开始找,从后往前找ch第一次出现的位置,没有返回-1 |
int lastIndexOf(String str) | int lastIndexOf(String str) |
int lastIndexOf(String str) | 从fromIndex位置开始找,从后往前找str第一次出现的位置,没有返回-1 |
public static void main(String[] args) {
String s1 = "hello";
char ch = s1.charAt(1);
System.out.println(ch);
System.out.println(s1.indexOf('e'));
System.out.println(s1.indexOf('e',3));
System.out.println(s1.indexOf("el"));
System.out.println(s1.lastIndexOf('l'));
}
- 数值和字符串转化
String s1 = String.valueOf(1234);
- 大小写转换
public static void main(String[] args) {
String s1 = "hello";
String s2 = "HELLO";
String ret = s1.toUpperCase();
System.out.println(s1);//对String的修改,不会对原来的值进行修改,会产生一个新的字符串
System.out.println(ret);
System.out.println(s1.toLowerCase());
}
- 字符串转数组
public static void main(String[] args) {
String s1 = "hello";
char[] array = s1.toCharArray();
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
System.out.println();
String s2 = new String(s1);
System.out.println(s2);
}
- 格式化
String ret = String.format("%d,%d",10,20);
- 字符串替换
public static void main(String[] args) {
String s1 = "ababfhqwufh";
System.out.println(s1.replace("a","c"));
System.out.println(s1.replaceAll("b","|"));
}
//字符串是不可变对象,替换不修改当前字符串,而是产生一个新的字符串
- 字符串拆分
字符串拆分:可以将一个完整的字符串按照指定的分隔符划分为若干个子字符串
//1.字符“|”,“*”,“.”,“+”都得加上转义字符,前面加上"\\"
//2.如果是“\”,写成"\\\\"(\\表示\)
//3.如果一个字符串中有多个分隔符,可以用|作为连字符
public static void main(String[] args) {
String s1 = "hello world";
String[] ret = s1.split(" ");//split返回类型是一个数组
for (int i = 0; i < ret.length; i++) {
System.out.println(ret[i]);
}
String s2 = "19.168.1.1";
String[] ret2 = s2.split("\\.");
for (int i = 0; i < ret2.length; i++) {
System.out.println(ret2[i]);
}
String s3 = "name=zhangsan&age=19";
String[] ret3 = s3.split("&");
//第一次分割 name=zhangsan age=19
for (int i = 0; i < ret3.length; i++) {
String[] strings = ret3[i].split("=");
//第二次分割 name zhangsan age 19
for (String x : strings) {
System.out.println(x);
}
}
}
- 截取字符串
public static void main(String[] args) {
String s1 = "hello";
String ret = s1.substring(1);//截取指定位置开始的剩余字符串
System.out.println(ret);
String ret2 = s1.substring(1,3);//[1,3)截取方式为左闭右开
System.out.println(ret2);
}
- 字符串祛除空格
//去掉字符串中的左右空格,保留中间空格
public static void main(String[] args) {
String s1 = " hello world";
String ret = s1.trim();
System.out.println(ret);
}
字符串的不可变性
String是一种不可变对象,字符串中的内容是不可改变的,字符串不可被修改是因为:
1.String类在设计时是不可改变的,String类实现描述中已经说明
- String类中的实际字符保存在value字符数组中
- String被final修饰,表示该类不能被继承
- value被final修饰表示自己本身的值不能被修改,也不能修改引用的指向,但引用空间的值可以被修改
- 所有涉及修改字符串的,其实都是创建了一个新的对象,改变的是新的对象
final修饰的类表示该类不能被继承,final修饰引用类型表示该引用不能指向其他引用对象,但是引用的内容可以被修改,字符串不可变是因为被private修饰为私有的数组,只能在内部访问
字符串修改
避免直接对String类型对象进行修改,因为String类不能被修改,每次被修改都会创建一个新的对象,效率低下
public static void main(String[] args) {
String s = "hello";
s += "world";
System.out.println(s);
//底层实现的代码,会创建多个对象
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("hello");
stringBuilder.append("world");
String ret = stringBuilder.toString();
System.out.println(ret);
}
//尽量避免对String的直接需要,如果要修改建议尽量使用StringBuffer或者StringBuilder
StringBuilder和StringBuffer
方法 | 说明 |
---|---|
StringBuff append(Stringstr) | 在尾部追加,相当于String的+=,可以追加:boolean、char、char[]、double、float、int、long、Object、String、StringBuff的变量 |
int capacity() | 获取底层保存字符串空间总的大小 |
void ensureCapacity(intmininmumCapacity) | 扩容 |
StringBuffer insert(intoffset, String str) | 在offset位置插入:八种基类类型 & String类型 & Object类型数据 |
StringBuffer deleteCharAt(int index) | 删除index位置字符 |
StringBuffer reverse() | 反转字符串 |
String toString() | 将所有字符按照String的方式返回 |
public static void main(String[] args) {
StringBuilder s1 = new StringBuilder("hello");
StringBuilder s2 = s1;
//追加:即尾插 -> 字符,字符串,整型数字
s1.append("world");
System.out.println(s1);//helloworld
System.out.println(s1.length());//10 字符串有效长度
System.out.println(s1.capacity());//21 底层数组的总大小
System.out.println(s1.deleteCharAt(0));//删除首字符
System.out.println(s1.delete(0,3));//删除[0,3)范围的字符
System.out.println(s1.reverse());//字符串逆序
String ret = s1.toString();//将StringBuffer以String的方式返回
System.out.println(ret);
}
String和StringBuilder的最大区别就是String的内容无法被修改,而StringBuilder的内容可以修改
String和StringBuilder类不能直接转换,如果要互相转换需要以下原则
- String变为StringBuilder: 利用StringBuilder的构造方法或append()方法
- StringBuilder变为String: 调用toString()方法
String、StringBuilder、StringBuffer的区别
- String的内容不可修改,每次修改String对象意味着会创建一个新的String对象,StringBuffer与StringBuilder的内容可以修改.
- StringBuffer采用同步处理,属于线程安全操作;而StringBuilder未采用同步处理,属于线程不安全操作