目录
4.与StringBuffer StringBuilder转换
3.public int indexOf(String str)
4.public int lastIndexOf(String str)
5. public char charAt(int index)
6.String substring(int beginIndex, int endIndex)
7.boolean startsWith(String prefix)
8.boolean endsWith(String suffix)
9.int compareTo(String anotherString)
10.boolean equals(Object anObject)
11.boolean equalsIgnoreCase(String anotherString)
15.String replace(char oldChar, char newChar)
17.String[] split(String regex, int limit)
四.StringBuffer 和 StringBuilder
1. String StringBuffer StringBuilder 三者对比
一 基础
1.特点
1.底层是 final 的char形数组 private final char value[];
2.当字符重新赋值时 会在常量池新建一个(调用replace之后也不是对原来的进行修改)
3.类声明时 public final class String implements java.io.Serializable, Comparable<String>, CharSequence 即不能被继承
2.JVM字符串常量池存放位置说明
1.6 字符串常量池储存在方法区(永久区)
1.7 字符串常量池储存在堆空间
1.8 字符串常量池储存在方法区(元空间)
3.内存方面解析
注 堆:new出来的 常量池:不存在一模一样的字符串
@Test
public void test(){
String s1 = "hello";
String s2 = "hello";
String s3 = new String("hello");
System.out.println(s1==s2);//true 地址值相同
// 注意 Person p1 = new Person("Tom",123);
// Person p2 = new Person("Tom",123); p1.name==p2.name//true
// 这里的Tom相当于字面量创建的
System.out.println(s1 == s3);//false
s1 = "hi";
// 当变量修改时 即在变量中新建一个
System.out.println(s2);//hello
}
变量 s1放在栈中 常量池中先找是否有hello 如果没有则创建一个并把首地址值给s1;
变量 s2放在栈中 常量池中先找是否有hello 有则把首地址值给s2不再进行创建
变量 s3放在栈中 new出来(引用数据类型)的放在堆里(存的是地址值指向常量池中的hello(如果没有则创建))
创建s3时创建了2个对象 一个是堆里new的结构 另一个char[]对应的常量池中的数据”hello“;
4.字符串拼接
1.常量与常量的拼接结果在常量池 且常量池不会存在相同内容的常量
2只要其中一个是变量 结果就在堆中
3.如果拼接的结果调用 intern()方法 返回值就在常量池中
@Test
public void test1(){
String s1 = "hello" + "Word";
// String 通过变量方式进行拼接操作的 是在堆空间中进行(和new的方式相同)
String s11 = "hello" + "Word";
String s2 = "hello";
String s3 = new String("helloWord");
String s4 = "Word";
s2 +=s4;
// public native String intern();
//返回值时常量中池中此常量值已经存在的 helloWord
System.out.println(s2.intern() == s1);//true
System.out.println(s1 == s11);//true
System.out.println(s1==s2);//false
System.out.println(s2 == s3);//false
// 注 final String s = "t" 声明为final的进行拼接操作相当于常量
}
二.String 与其他结构的转化
1.与基本数据类型包装类的转化
1.String -> 基本数据类型,包装类:调用包装类的静态方法 parseXxx(str)
2.基本数据类型 -> String 调用String重载的valueOf(xxx)
String s = "1";
System.out.println(Integer.parseInt(s));//1
int i = 2;
System.out.println(String.valueOf(i));//2
2.与char形数组
1.char[] -> String 调用String构造器
2.String -> char[] toCharArray()
char[] c = new char[]{'s','t','r'};
String s1 = "str";
String s3 = new String(c);
char[] chars = s1.toCharArray();
3.与byte[]之间的转换
1.编码 String ->byte[] getBytes(StandardCharsets.UTF_8) 字符串 ->字节
2.解码 byte[] -> String 调用String构造器 字节 -> 字符串
注:字符编码一致,否则乱码
String s2 = "s";
byte[] bytes = s.getBytes(StandardCharsets.UTF_8);
String s4 = new String(bytes);
4.与StringBuffer StringBuilder转换
1.String -> StringBuffer StringBuilder:调用其构造器
2.StringBuffer StringBuilder -> String 调用其构造器或者 StringBuffer StringBuilder 的toString()方法
String s5 = "ss";
StringBuffer stringBuffer = new StringBuffer(s5);
StringBuilder stringBuilder = new StringBuilder(s5);
String s6 = stringBuilder.toString();
String s7 = stringBuffer.toString();
String s8 = new String(stringBuffer);
String s9 = new String(stringBuilder);
三 String的常用方法
1.测试用的代码
String str = "hello,word";
String str1 = "hello,word1";
String str2 = "Hello,word";
String str3 = " hello,w ord ";
String str4 = "h,e,l,l,o,wo,r,d";
2.int length()
// 获取字符串多少个字符
System.out.println(str.length());//10
3.public int indexOf(String str)
// 从头开始查找str在字符串中第一次出现的位置
System.out.println(str.indexOf("ll"));//2
// public int indexOf(String str, int fromIndex)
//从下标fromIndex处开始开始查找str在字符串中第一次出现的位置
System.out.println(str.indexOf("o", 5));//7
4.public int lastIndexOf(String str)
// 从尾部开始查找str在字符串中第一次出现的位置
System.out.println(str.lastIndexOf("o"));//7
5. public char charAt(int index)
// 查找字符串中下标为index位置出现的字符
System.out.println(str.charAt(2));//l
6.String substring(int beginIndex, int endIndex)
// 从fromIndex处开始截取到endIndex处结束
// 截取后不会改变str的字符
System.out.println(str.substring(1,3));//el
// String substring(int beginIndex) 从beginIndex处开始截取到最后
System.out.println(str.substring(0));//hello,word
7.boolean startsWith(String prefix)
// boolean startsWith(String prefix) 验证第一个字符
System.out.println(str.startsWith("h"));//true
// public boolean startsWith(String prefix, int toffset)
// 从指定位置开始 验证第一个
System.out.println(str.startsWith("e", 1));//true
8.boolean endsWith(String suffix)
// 验证最后一个字符
System.out.println(str.endsWith("d"));//true
9.int compareTo(String anotherString)
//按字典的顺序比较 从第一个字符开始 如果不同 return str[0]-str[1]
// 相同接着比,比到最短字符串的长度 如果还相同 return str.length-str1.length
System.out.println(str.compareTo(str1));
//-1 因为都相同 所以return str.length-str1.length
10.boolean equals(Object anObject)
// 比较两个字符串的内容是否一样
// if是否是原来的 str 然后if anObject 是否是String
// 然后if 长度是否相同 最后再一个一个比
System.out.println(str.equals(str1));//false
11.boolean equalsIgnoreCase(String anotherString)
// 忽略大小写进行比较
System.out.println(str.equalsIgnoreCase(str2));//true
12.String concat(String str)
// 用concat拼接两个字符成为一个新的字符串。
System.out.println(str.concat(str1));//hello,wordhello,word1
13.String toUpperCase()
// 全部转大写
System.out.println(str.toUpperCase());//HELLO,WORD
14.String toLowerCase()
// 全部转小写
System.out.println(str.toLowerCase());//hello,word
15.String replace(char oldChar, char newChar)
// 用新的字符代替原来字符
System.out.println(str.replace("ll", "gg"));//heggo,word
System.out.println(str);//hello,word
16.String trim()
// 清除字符串str两侧的空字符串
System.out.println(str3.trim());//hello,w ord
17.String[] split(String regex, int limit)
//依据正则表达式分割 这里以","分割 分的组数不超过limit
String[] split = str4.split(",", 2);
for (String s:
split) {
System.out.println(s);
}
// h
//e,l,l,o,wo,r,d
// String[] split(String regex) 依据正则表达式分割 这里以","分割
String[] split1 = str4.split(",");
for (String s:
split1) {
System.out.print(s+"!");
}
// h!e!l!l!o!wo!r!d!
四.StringBuffer 和 StringBuilder
1. String StringBuffer StringBuilder 三者对比
1.底层 都是char形数组
2.String 不可变 频繁进行修改操作时效率最低
3.StringBuffer 可变 线程安全 效率低于 StringBuilder 继承于AbstractStringBuilder
4.StringBuilder 可变 效率最高 jdk1.5新增 继承于AbstractStringBuilder
2.底层原理
1.
public StringBuffer() {super(16); }
StringBuffer(String str) {super(str.length() + 16);
底层创建一个长度是16的数组
2.扩容是时 2倍长度*2 +2 将原来的数组赋值给新创建的数组 int newCapacity = (value.length << 1) + 2;
3.常用方法
@Test
public void test9(){
// 初始化
StringBuffer sb = new StringBuffer("hello,word");
// 增 append(boolean b) append(char c) append(int i) append(char[] str, int offset, int len)
sb.append(1);
System.out.println(sb);//hello,word1
// 删 delete(int start, int end) 删除多个字符
sb.delete(1,3);
System.out.println(sb);//hlo,word1
// deleteCharAt(int index) 删除指定位置
sb.deleteCharAt(2);
// 改 void setCharAt(int index, char ch) 只能是char
sb.setCharAt(0,'s');
System.out.println(sb);//sl,word1
// 插
// insert(int offset, Object obj) 第一个是要插入的下标,第二个也可以是基本数据类型 可以是char形数组
sb.insert(0,2);
System.out.println(sb);//2sl,word1
// 遍历
for (int i = 0; i < sb.length(); i++) {
System.out.print(sb.charAt(i)+" ");
}
//2 s l , w o r d 1
// 其他
// 反转字符串 StringBuffer reverse()
System.out.println(sb.reverse());//1drow,ls2
// int indexOf(String str) 查询指定字符串的下标 返回第一个 int indexOf(String str, int fromIndex) 从第几个开始
System.out.println(sb.indexOf("rd"));//-1 反转之后未找到
// int lastIndexOf(String str) int indexOf(String str, int fromIndex)
System.out.println(sb.lastIndexOf("rd", 2));//-1 反转之后未找到
// 截取 String substring(int start, int end) String substring(int start) 返回的是String 左闭右开
System.out.println(sb.substring(1, 5));//drow
// 替换 StringBuffer replace(int start, int end, String str)
System.out.println(sb.replace(1, 5, "mm"));//1mm,ls2
}