入门-String中常用的方法 buffer、builder区别
- 字符串比较
当我们想要比较两个字符串是否相同时,要特别注意,我们实际上是想比较字符串的内容是否相同。必须使用equals()方法而不能用==。
public class Main {
public static void main(String[] args) {
String s1 = "hello";
String s2 = "hello";
System.out.println(s1 == s2);
System.out.println(s1.equals(s2));
}
}
从表面上看,两个字符串用==和equals()比较都为true,但实际上那只是Java编译器在编译期,会自动把所有相同的字符串当作一个对象放入常量池,自然s1和s2的引用就是相同的。
所以,这种==比较返回true纯属巧合。换一种写法,==比较就会失败:
public class Main {
public static void main(String[] args) {
String s1 = "hello";
String s2 = "HELLO".toLowerCase();
System.out.println(s1 == s2);
System.out.println(s1.equals(s2));
}
}
- 三个方法的使用:length() substing() chatAt()
public static void main(String[] args) { //定义一个字符串"晚来天欲雪 能饮一杯无" 注意下方的注释有问题以示例为正确打印
String str = "晚来天欲雪 能饮一杯无";
System.out.println("字符串的长度是:"+str.length()); //字符串的雪字打印输出 charAt(int index)
System.out.println(str.charAt(4)); //
System.out.println(str.substring(2)); //取出子串取出从index2开始直到最后的子串,包含2
System.out.println(str.substring(2,4)); //取出index从2到4的子串,包含2不包含4 顾头不顾尾
}
输出示例:
字符串的长度是:11
雪
天欲雪 能饮一杯无
天欲
两个方法的使用,求字符或者子串第一次or最后一次在字符串中出现的位置:indexOf() lastIndexOf()
package com.mpp.string;
public class StringDemo2 {
public static void main(String[] args) {
String str = new String("赵客缦胡缨 吴钩胡缨霜雪明");
//查找胡在字符串中第一次出现的位置
System.out.println("\"胡\"在字符串中第一次出现的位置:"+str.indexOf("胡"));
//查找子串"胡缨"在字符串中第一次出现的位置
System.out.println("\"胡缨\"在字符串中第一次出现的位置"+str.indexOf("胡缨"));
//查找胡在字符串中最后一次次出现的位置
System.out.println(str.lastIndexOf("胡"));
//查找子串"胡缨"在字符串中最后一次出现的位置
System.out.println(str.lastIndexOf("胡缨"));
//从indexof为5的位置,找第一次出现的"吴"
System.out.println(str.indexOf("吴",5));
}
}
输出示例:
"胡"在字符串中第一次出现的位置:3
"胡缨"在字符串中第一次出现的位置3
8
8
6
- 字符串与byte数组之间的相互转换
package com.mpp.string;
import java.io.UnsupportedEncodingException;
public class StringDemo3 {
public static void main(String[] args) throws UnsupportedEncodingException { //字符串和byte数组之间的相互转换
String str = new String("hhhabc银鞍照白马 飒沓如流星"); //将字符串转换为byte数组,并打印输出
byte[] arrs = str.getBytes("GBK");
for(int i=0;i){
System.out.print(arrs[i]);
} //将byte数组转换成字符串
System.out.println();
String str1 = new String(arrs,"GBK"); //保持字符集的一致,否则会出现乱码
System.out.println(str1);
}
}
示例(出现报错,待解决):
1、在字符串不经常发生变化的业务场景优先使用String(代码更清晰简洁)。如常量的声明,少量的字符串操作(拼接,删除等)。
2、在单线程情况下,如有大量的字符串操作情况,应该使用StringBuilder来操作字符串。不能使用String"+"来拼接而是使用,避免产生大量无用的中间对象,耗费空间且执行效率低下(新建对象、回收对象花费大量时间)。如JSON的封装等。
3、在多线程情况下,如有大量的字符串操作情况,应该使用StringBuffer。如HTTP参数解析和封装等。
String str1 = "a";
String str2 = "b";
String str3 = "ab";
String str4 = str1 + str2;
String str5 = new String("ab");
System.out.println(str5.equals(str3));
System.out.println(str5 == str3);
System.out.println(str5.intern() == str3);
System.out.println(str5.intern() == str4);
true
false
true
false
为什么会得到这样的一个结果呢?我们一步一步的分析。
第一、str5.equals(str3)这个结果为true,不用太多的解释,因为字符串的值的内容相同。
第二、str5 == str3对比的是引用的地址是否相同,由于str5采用new String方式定义的,所以地址引用一定不相等。所以结果为false。
第三、当str5调用intern的时候,会检查字符串池中是否含有该字符串。由于之前定义的str3已经进入字符串池中,所以会得到相同的引用。
第四,当str4 = str1 + str2后,str4的值也为”ab”,但是为什么这个结果会是false呢?先看下面代码
String a = new String("ab");
String b = new String("ab");
String c = "ab";
String d = "a" + "b";
String e = "b";
String f = "a" + e;
System.out.println(b.intern() == a);
System.out.println(b.intern() == c);
System.out.println(b.intern() == d);
System.out.println(b.intern() == f);
System.out.println(b.intern() == a.intern());
false
true
true
false
true
//字符串的equals方法
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
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;
}
- StringBuffer和StringBuilder
/*
- The value is used for character storage →该值用于字符存储
*/
char[] value; //初始化容量为16
/*
-Constructs a string builder with no characters in it and an initial capacity of 16 characters
→构造一个StringBuilder不包含字符且初始容量为16个字符
*/
public StringBuilder(){
super(16); //这两类的append方法都是来自父类AbstractStringBuilder的方法
}
public AbstractStringBuilder append(String str){
if(str == null)
return appendNull();
int len = str.length();
ensureCapacityInternal(count + len);
str.getChars(0, len, value, count);
count += len;
return this;
}
@Override
public StringBuilder append(String str){
super.append(str);
return this;
}
@Override
public synchronized StringBuffer append(String str){
toStringCache = null;
super.apped(str);
return this;
}
- append方法
Stringbuffer在大部分涉及字符串修改的操作上加了synchronized关键字来保证线程安全,效率较低。
未完待续…
参考:
菜鸟教程—>String类型
https://blog.csdn.net/a724888/article/details/80048782