使用HashMap遍历出现对象地址且值无法递增,求排查方案
问题分析与修复
你的代码里有两个核心问题,直接导致了遇到的现象:
1. char数组转String的方式错误
你用sub.toString()来把排序后的char数组转成字符串,但数组的toString()方法默认返回的是对象的内存地址(格式类似[C@xxxxxx),而不是数组里的字符内容。这就引发了连锁问题:
- 哪怕两个子串排序后字符完全一致(比如"ab"和"ba"排序后都是
['a','b']),sub.toString()返回的内存地址也不一样,导致每次生成的s1都是唯一的 - 因为
s1永远不会重复,map.containsKey(s1)永远为false,代码永远走map.put(s1,1)分支,值自然始终保持为1 - 遍历keySet时,输出的都是这些内存地址字符串,而不是你期望的字符组合
正确的转换方式是用new String(sub)或者String.valueOf(sub)来将char数组转为对应字符串:
String s1 = new String(sub);
2. 关于map.get(s1)返回null的问题
这其实是第一个错误的连锁反应:因为每次的s1都是全新的内存地址,之前从未被存入map,所以else分支根本不会被触发——containsKey(s1)永远为false。如果是在if分支里调用map.get(s1),返回null是正常的,因为这个s1还没被put进map。
修复后的完整代码
import java.util.Arrays; import java.util.HashMap; public class Main { public static void main(String[] args) { String s = "abba"; HashMap<String, Integer> map = new HashMap<>(); for (int i = 0; i < s.length(); ++i) { for (int j = i + 1; j <= s.length(); ++j) { char[] sub = s.substring(i, j).toCharArray(); Arrays.sort(sub); // 修正数组转字符串的方式 String s1 = new String(sub); if (!map.containsKey(s1)) { map.put(s1, 1); } else { map.put(s1, map.get(s1) + 1); } } } for (String key : map.keySet()) { System.out.println(key + " " + map.get(key)); } } }
运行后会得到符合预期的输出:
a 2 ab 2 abb 1 abba 1 b 2 bb 1
内容的提问来源于stack exchange,提问作者ss_rn
相关产品推荐
相关产品推荐

