从一道leetcode题看字符串在内存中的位置与其创建方式的关系

题目描述:

  给定一个仅包含数字2-9的字符串,返回所有它所能表示的字母组合,给出数字到字母的映射如下:

    2 :abc"

    3 :"def"

    4 :"ghi"

    5 :"jkl"

    6 :"mno"

    7 :"pqrs"

    8 :"tuv"

    9 :"wxyz"

  以下是官方给的题解:  

 1 import java.util.*;
 2 
 3 public class Solution {
 4     private Map<String, String> map = new HashMap<String, String>() {
 5         {
 6             put("2", "abc");
 7             put("3", "def");
 8             put("4", "ghi");
 9             put("5", "jkl");
10             put("6", "mno");
11             put("7", "pqrs");
12             put("8", "tuv");
13             put("9", "wxyz");
14         }
15     };
16     
17     private List<String> result = new ArrayList<>();
18     
19     public List<String> letterCombinations(String digits) {
20         if(digits != null && digits.length() != 0)
21         {
22             findCombination("", digits);
23         }
24         return result;
25     }
26     
27     public void findCombination(String combination, String next_digits)
28     {
29         if(next_digits.length() == 0)    //注意这里不能直接用next_digits == ""而应该用next_digits.equals("")
30         {
31             result.add(combination);
32             return;
33         }
34         String letters = map.get(next_digits.substring(0, 1));
35         for(int letter = 0; letter < letters.length(); letter++)
36         {
37             findCombination(combination+letters.charAt(letter), next_digits.substring(1));
38         }
39     }
40 }

  其中第49行有两种判断方法,一种是判断字符串的长度是否为0,另一种是直接判断字符串是否为空字符串,但是此处如果直接使用next_digits==""则会出错,因为==判断的是对象引用相等性,即只有等号两边的对象是同一个对象(即存储地址相同)时,才会返回true,而因为substring方法返回的空字符串是一个新字符串,存放在堆中,而""是在常量池中,所以虽然二者从内容来看是相等的,但存储地址并不相等,所以如果使用next_digits==""作为判断条件,则返回的永远是false,导致出现索引越界异常。

  所以字符串的不同创建方式会可能会导致存储地址的不同,需要注意,对于对象的相等性判断一般是采用equals方法,而Object方法的equals方法正是使用==来判断的,所以继承自Object方法的equals方法只能判断对象引用相等性而不能判断对象内容相等性,这也是为什么我们一般要重写equals方法的原因。

原文地址:https://www.cnblogs.com/OoycyoO/p/11718559.html