入门系列-String中常用的方法 buffer、builder区别

入门-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);
    }
}
示例(出现报错,待解决):

  • String、String builder和String buffer的区别

1、在字符串不经常发生变化的业务场景优先使用String(代码更清晰简洁)。如常量的声明,少量的字符串操作(拼接,删除等)。

2、在单线程情况下,如有大量的字符串操作情况,应该使用StringBuilder来操作字符串。不能使用String"+"来拼接而是使用,避免产生大量无用的中间对象,耗费空间且执行效率低下(新建对象、回收对象花费大量时间)。如JSON的封装等。

3、在多线程情况下,如有大量的字符串操作情况,应该使用StringBuffer。如HTTP参数解析和封装等。

  • String类型的intern

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
  • String类型的equals

//字符串的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


版权声明:本文为qq_43298296原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。