Java String equals和==的详细介绍

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java String equals和==的详细介绍相关的知识,希望对你有一定的参考价值。

Java String
越多越好 copy也好 只要内容有价值就好
如果能简短的说明那就更好了
可是 我经常用string==啊 大部分时候都没有问题 个别时候才有问题··
能解释下么···还有最好是能详细点
------------------------
貌似 user_pyw 说反了吧···
不过按反着的意思理解 倒是你这个比较符合我的愿望答案
chlsgo 准确详细 就选你了吧
大时代暑 说的有点绕
本人对名词不怎么理解 ··不过看大致意思应该是
==对比的对象本身
equals对比的是对象内的值
---------------------
bochm说的看似不错 不过有点慢了·

equals 是比较的两个字符串是否一样
比如 “asd”.equals(“asd”)==true;
"==" 它比较的是两个“引用”
比如:
String a=new String ("a");
String b=new String ("a");
System.out.println(a==b)它就输出false了
因为不是一个引用啊(虽然都是a);
参考技术A 1.String类的equals方法是字符串字面量的比较,如 :
String a = "aaa";
String b = "aaa";
a.equals(b) 就返回true

2.==操作符是字符串指针(内存地址)的比较,如:
String a = "aaa";
String b = "aaa"; //如果写成 String b = a; a == b 就返回true
a == b 就返回false
参考技术B 对于String而言,String自己实现了equals方法,equals比较的是两个字符串对应的char[] 值是否完全相同(Sting 对象的值时通过char[] 存储的。比如两个String 对象 str1, str2,其中 str1 值为"123",那么其对应的char[] 值为['1', '2', '3']。str2值也为"123",其char[]值也为['1', '2', '3']。在equals方法中,通过比较这两个字符串数组的长度以及每一位的值是否都相等。如果都相等,则equals的返回值为 true,否则为false)。而 == 比较的是两个对象引用地址是否相同。我们通过 new String("") 构造出的是两个对象,其对应的对象引用地址自然是不同的。 参考技术C equals:判断2个引用变量是否指向同一个对象

==:除了可以判断2个引用变量是否指向同一个对象之外,还 可以2个基本类型的变量是否相等
参考技术D Java中String类型的比较只能用.equals.
int.double一类的才能用==
原因那要就提到存放到cpu的问题.
一个是存放到堆中..一个存放到栈中..
堆中的是存放的数据..
栈是存放的坐标...

String.equals() 如何工作

【中文标题】String.equals() 如何工作【英文标题】:how does String.equals() work 【发布时间】:2012-09-30 12:45:14 【问题描述】:

我一直在尝试了解一些 API 方法的工作原理

下面是java.lang.String类的equals方法的sn-p

有人能告诉我代码是如何比较两个字符串的吗? 我明白计数的意义,但偏移意味着什么。这些变量如何获得值?

就像我创建一个字符串一样。这些是如何初始化的。

详细的逐行描述以及实例变量、值、计数、偏移量等初始化的方式和时间??

 public boolean equals(Object anObject) 
  1014           if (this == anObject) 
  1015               return true;
  1016           
  1017           if (anObject instanceof String) 
  1018               String anotherString = (String)anObject;
  1019               int n = count;
  1020               if (n == anotherString.count) 
  1021                   char v1[] = value;
  1022                   char v2[] = anotherString.value;
  1023                   int i = offset;
  1024                   int j = anotherString.offset;
  1025                   while (n-- != 0) 
  1026                       if (v1[i++] != v2[j++])
  1027                           return false;
  1028                   
  1029                   return true;
  1030               
  1031           
  1032           return false;
  1033       

【问题讨论】:

【参考方案1】:

逻辑上

while (n-- != 0) 
if (v1[i++] != v2[j++])
    return false;

相同
for (int i = 0; i < n; i++) 
    if (v1[i] != v2[j])
        return false;
    

我不确定为什么 JVM 设计者会这样做。也许使用 while 循环比使用 for 循环可以提高性能。它在我看来很像 C,所以也许写这篇文章的人有 c 的背景。

Offset 用于定位字符串在 char 数组中的起始位置。内部字符串存储为 char 数组。这是value

if (v1[i++] != v2[j++])
    return false;

检查字符串底层 char 数组中的字符。

一行一行

如果引用指向同一个对象,则必须等号

1014           if (this == anObject) 
1015               return true;
1016           

如果对象是字符串,则检查它们是否相等

1017           if (anObject instanceof String) 

将传入的参数转换为字符串。

1018               String anotherString = (String)anObject;

记住this.string的长度

1019               int n = count;

如果两个字符串的长度匹配

1020               if (n == anotherString.count) 

得到一个字符数组(值就是这个数组)

1021                   char v1[] = value;
1022                   char v2[] = anotherString.value;

找出这个数组中字符串的开始位置

1023                   int i = offset;
1024                   int j = anotherString.offset;

遍历 char 数组。如果值不同则返回false

1025                   while (n-- != 0) 
1026                       if (v1[i++] != v2[j++])
1027                           return false;
1028                   

其他的都必须是真的

1029                   return true;
1030               
1031           

如果不是String类型,则它们不能相等

1032           return false;
1033       

要了解偏移量和值,请查看 String 类

/** The value is used for character storage. */
private final char value[];

/** The offset is the first index of the storage that is used. */
private final int offset;

/** The count is the number of characters in the String. */
private final int count;

构造函数初始化这些变量。默认构造函数代码如下。对于其他构造函数,您应该会看到类似的内容。

/**
  * Initializes a newly created @code String object so that it represents
  * an empty character sequence.  Note that use of this constructor is
  * unnecessary since Strings are immutable.
  */
 public String() 
    this.offset = 0;
    this.count = 0;
    this.value = new char[0];
 

This 是一个很好的链接查看

【讨论】:

太干净了。。谢谢。 还有一个问题,我找不到初始化这些实例变量的构造函数。有吗?这是由 JVM 处理的吗? 刚刚用默认的 ctor 更新了这些被初始化的字符串的答案 谢谢伙计。很好的答案。【参考方案2】:

您可能知道 Java 中的字符串处理是一种特殊情况,大多数情况下,字符串是从字符串池中分配的,因此对于 char 数组"I am Learning Java",可能会出现一个字符串引用点到"I am Learning Java",则偏移量为0,其他字符串可能指向"am",因此偏移量为2由于一些本机代码处理其初始化,所以我认为在该过程中设置了偏移量。(在从字符串池共享内存期间)

从代码中也可以看出

 public String(String original) 
         int size = original.count;
        char[] originalValue = original.value;
        char[] v;
        if (originalValue.length > size) 
            // The array representing the String is bigger than the new
          // String itself.  Perhaps this constructor is being called
            // in order to trim the baggage, so make a copy of the array.
           int off = original.offset;
          v = Arrays.copyOfRange(originalValue, off, off+size);
         else 
           // The array representing the String is the same
          // size as the String, so no point in making a copy.
            v = originalValue;
       
      this.offset = 0;
       this.count = size;
       this.value = v;
    

当从旧字符串创建新字符串时,旧字符串(在这种情况下为原始字符串)可能来自字符串池,这就是为什么首先获取偏移量然后复制整个数组以分配新字符串的原因内存(新字符串不从字符串池共享内存)

另外你应该记住 String 是一个派生类型并且字符串总是存储在一个字符数组中,所以我们需要一个偏移量来确定字符串在字符数组中的起始位置。

【讨论】:

以上是关于Java String equals和==的详细介绍的主要内容,如果未能解决你的问题,请参考以下文章

强烈推荐浅谈Java中String.equals()和==的区别

强烈推荐浅谈Java中String.equals()和==的区别

java中String的equals()和 ==

Java:String和int变量上的equals()和===

Java中equals和“==””的区别,String特殊

java string ==和equals的使用