Java中的对象引用对于不同的对象有什么不同?
想知道以下方法的区别,即为什么两个相同(逻辑上相同)的方法不返回相同的预期结果:
方法:创建字符地图和单词列表:
void setMapping(List<String> words) { Map<Character, List<String>> wordsByLetter = new HashMap<>(); for (String word : words) { char letter = word.toLowerCase().charAt(0); List<String> ref = wordsByLetter.get(letter); if (ref == null) { ref = new ArrayList<>(); wordsByLetter.put(letter, ref); } ref.add(word); } }
所以在本例中,我们引用了一个名为“ref”的字符串列表,每次调用方法“add”时,它都会被更新。 不幸的是,同样的方法不适用于第二种方法:
第2种方法:统计所有外观:
void countCategories(List<String> categories) {
Map<String, Integer> mapper = new HashMap<>();
for (String category : categories) {
//need object Integer either to provide reference to it and to check whether it is a null
Integer counter = mapper.get(category);
if (counter == null) {
counter = 0;
//DOESN'T WORK THE SAME WAY:
//mapper.put(category, counter);
}
counter++;
mapper.put(category, counter);
}
}
所以,我的问题是,为什么第二种方法的工作方式与第一种不同,也就是说,为什么我们不能通过对象引用更新特定集合中的计数器
# 1 楼答案
区别来自映射值的可变性:
List<String>
是可变的,而Integer
是不可变的您的第二个代码段可以通过添加
else
来修复,如下所示:或不带
if
的等价条件表达式# 2 楼答案
counter
是Integer
类的对象,这意味着它是不可变的。因此,无法更新其值counter++
返回一个新的Integer
实例,并将其分配给counter
变量。因此,如果在counter++
之前调用mapper.put(category, counter)
,则counter
引用的原始对象存储在HashMap
中,并且counter++
语句对HashMap
的内容没有影响这就是为什么以下代码不起作用的原因:
相反,你必须写:
第一个片段,在
ArrayList
中存储ArrayList
的地方是不同的,因为ArrayList
是可变的,并且调用add
来调用ArrayList
中已经存储的HashMap
会使ArrayList
发生突变