java笔记(一):String,StringBuffer,StringBuilder

主要记录java中的String赋值及比较的问题以及StringBuffer和StringBuilder

  • 比较:==和.equals
  • 赋值:= 和 new String(“”)

比较:==和.equals

java中,除了基本数据类型(int, short, long, byte, char, boolean, float, double)存储的是值本身外,其他的数据类型存储的都是对象的引用(或者称为对象的地址)。

int a = 1, b = 1;
String str1 = new String("hello");
String str2 = new String("hello");
System.out.println(a == b); //true
System.out.println(str1 == str2); //false

a,b存储的都是1这个值。
而str1,str2存储的是新建的String对象的地址,两个地址不同。

//接上
System.out.println(str1.equals(str2)); //true

查看java源码中对于String的equals方法的实现:

/**
该方法覆盖了Object中的equals方法,其实不仅是String,Integer、Double等都对Object的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;
}

赋值:= 和 new String(“”)

String str1 = "hello";
String str2 = "hello";
System.out.println(str1 == str2); //true

何故?
查阅资料,解释如下:
使用”=”为String变量赋值时,会先在字符串缓冲区查找有没有该字符串,若没有,则在字符串缓冲区新建该字符串,并将地址返回;若有,则直接将该字符串在缓冲区的地址付给变量。
使用”new String()”时,首先也会去缓冲区里边查找,不管有没有,它都会在堆里新建一个该字符串对象并返回该对象的地址,如果缓冲区里面没有,则在缓冲区里面也新建一个。

String str1 = "hello world";
String str2 = "hello";
/**
"hello"+" world"在编译的过程中间就将加直接处理成了"hello world";
而str2+" world"则被处理为new StringBuffer("hello").append(" world").toString();
*/
System.out.println(str1 == "hello"+" world"); //true
System.out.println(str1 == str2+" world"); //false

StringBuffer

StringBuffer和String都用来表示字符串,但两者是不同的类。
StringBuffer在进行字符串处理时,不生成新的对象,在内存使用上要优于String类。
StringBuffer在实现上和String一样同样适用char[]。但在append操作时,使用System.copyarray()方法(该方法会经常出现),提高了效率。
StringBuffer是线程安全的
StringBuffer在拼接字符串时的方法:
public StringBuffer append(String s)

StringBuilder

StringBuilder和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的,但速度比StringBuffer快(不能同步访问)。

String, StringBuffer, StringBuilder都不是java基本类型,而是类。
三者在存储数据事都是用char[] value.
不同之处在于String的value被final修饰过,其他两者没有。

String的内部实现

public final class String implements ... {
    /** The value is used for character storage. */
    private final char value[];

可以看出,String内部是使用char数组来保存数据的。value值被final修饰,意味着只能初始化一次。
由此引申出关于函数字符串传参的问题。

Java 编程语言只有值传递参数。当一个对象实例作为一个参数被传递到方法中时,参数的值就是该对象的引用的地址。

public static void main(String[] args){
    String str1 = "hello";
    String str2 = "world";
    change(str1, str2);
    System.out.println(str1+" "+str2); //输出hello world
}

public static void change(String str1, String str2){
    str1 = str2;
    str2 = str1+str2;
}

可能很部分人想的不一样,String也是对象,但主函数中的str1,str2却不受影响。
由上所述,函数传递的其实是对象的地址,也就是说将str1和str2两个地址传给了函数内部,无论函数内部的数据如何更改,但主程序中的变量的地址是不变的,而字符串又是不变的,只能初始化一次,因此对于传递字符串变量的函数来说,外部的字符串变量的数据是不会改的。
变量描述
参考资料:
http://blog.csdn.net/kingzone_2008/article/details/9220691

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值