有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java中的对象引用对于不同的对象有什么不同?

想知道以下方法的区别,即为什么两个相同(逻辑上相同)的方法不返回相同的预期结果:

  1. 方法:创建字符地图和单词列表:

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

所以,我的问题是,为什么第二种方法的工作方式与第一种不同,也就是说,为什么我们不能通过对象引用更新特定集合中的计数器


共 (2) 个答案

  1. # 1 楼答案

    区别来自映射值的可变性:List<String>是可变的,而Integer是不可变的

    您的第二个代码段可以通过添加else来修复,如下所示:

    if (counter == null) {
        mapper.put(category, 1);
    } else {
        mapper.put(category, counter+1);
    }
    

    或不带if的等价条件表达式

    mapper.put(category, (counter != null ? counter : 0) + 1);
    
  2. # 2 楼答案

    counterInteger类的对象,这意味着它是不可变的。因此,无法更新其值

    counter++返回一个新的Integer实例,并将其分配给counter变量。因此,如果在counter++之前调用mapper.put(category, counter),则counter引用的原始对象存储在HashMap中,并且counter++语句对HashMap的内容没有影响

    这就是为什么以下代码不起作用的原因:

    Integer counter = mapper.get(category);
    if (counter == null) {
      counter = 0;
      mapper.put(category, counter);
    }
    counter++;
    

    相反,你必须写:

    Integer counter = mapper.get(category);
    if (counter == null) {
      counter = 0;
    }
    counter++;
    mapper.put(category, counter);
    

    第一个片段,在ArrayList中存储ArrayList的地方是不同的,因为ArrayList是可变的,并且调用add来调用ArrayList中已经存储的HashMap会使ArrayList发生突变