zoukankan      html  css  js  c++  java
  • Java中String推断相等equals与==的差别以及StringBuilder的equals

    Java中String类型具有一个equals的方法能够用于推断两种字符串是否相等,可是这样的相等又与运算符==所推断的“相等”有所不同,接下来进行分析,结论由程序进行验证

    String的equals函数仅仅要两个字符串“看起来”相等,就能够返回true,“看起来”相等意思指的是,当两个字符串对象所存放的内容同样时,不须要存放的内存地址同样,可是==推断则仅仅有当推断的两个变量所使用的内存地址为同样时才返回true。比如有两个长得一模一样的双胞胎A,B,若使用A==B来推断会返回false。使用A.equals(B)则会返回true。

    我们能够看object中的equals函数的源代码为

    public boolean equals(Object obj) {
            return (this == obj);
        }

    我们知道Java中全部的对象都默认继承自Object类。所以当我们没有重写equals的方法时,若使用equals来推断两个对象的是否相等时。仅仅有这两个对象指向的是同一个内存地址时。才会返回true,否则即使内容全然同样但在内存中是两个不同的内存地址也是返回false,此时若用双胞胎A,B来对照。A==B与A.equals(B)返回的都是false。

    既然如此,那String的equals与==为什么会不一样呢,这里我们要看一下String中重写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;
        }
    能够看出String中的equals函数首先推断其内存地址是否为同一个:

     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;
                }
            }

    当我们使用字符串连接--连接方式一般为+或concat("substring")--的方式创建字符串时,都会构建一个新的String对象。即在内存中开辟一个新的地址来存放,所以这个时候即使内容同样。用==推断的话,也是返回false;当我们使用等号赋值时,若内存中有该字符串。则该变量指向此内存地址二不是又一次创建一个,所以此时用==时会返回true,我们看一下例程:

    public class StringTest01 {
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    
    			String hello="hello";
    			String hel1=hello;
    			String hel2="hel";
    			String hel3=hel2+"lo";
    			String hel4=hel2.concat("lo");
    			
    			System.out.println(hello);
    			System.out.println(hel1);
    			System.out.println(hel3);
    			System.out.println(hel4);
    			//==等号測试
    			System.out.println(hello==hel1);
    			System.out.println(hello==hel3);
    			System.out.println(hello==hel4);
    			System.out.println(hel3==hel4);
    			
    			//equals函数測试
    			System.out.println(hello.equals(hel1));
    			System.out.println(hello.equals(hel3));
    			System.out.println(hello.equals(hel4));
    			System.out.println(hel3.equals(hel4));
    			
    			//StringBuilder測试
    			StringBuilder helloBuilder = new StringBuilder("hel");
    			System.out.println(helloBuilder.equals(hel2));
    	}
    
    }

    其输出结果为:


    最后一个StringBuilder的測试我们发现尽管使用equals来推断,可是返回的是false。这是为什么呢?

    首先。当我们使用StringBuilder创建对象时。肯定会在内存中开辟一个新的专属的地址用于存放对象内容。可是即使StringBuilder中存放的内容与其它字符串的内容同样,使用equals来推断也是返回false,这是由于StringBuilder并没有重写equals函数。即StringBuilder的equals为:

    public boolean equals(Object obj) {
            return (this == obj);
        }
    所以会返回false。



  • 相关阅读:
    【cf932E】E. Team Work(第二类斯特林数)
    【bzoj5093】[Lydsy1711月赛]图的价值(NTT+第二类斯特林数)
    斯特林数及斯特林反演
    Codeforces Round #608 (Div. 2)
    【cf1272】F. Two Bracket Sequences
    Codeforces Round #606 (Div. 2)
    【hdu4045】Machine scheduling(dp+第二类斯特林数)
    【poj2661】Factstone Benchmark(斯特林公式)
    [USACO1.4] Packing Rectangles
    [CF1313D] Happy New Year
  • 原文地址:https://www.cnblogs.com/zhchoutai/p/8278889.html
Copyright © 2011-2022 走看看