【问题标题】:populated HashMap created inside a Constructor returns null when instance object is referenced当引用实例对象时,在构造函数中创建的填充 HashMap 返回 null
【发布时间】:2013-03-13 05:09:36
【问题描述】:

第一次在这里发布海报。我通过stackoverflow搜索但找不到这个问题的任何答案,也许我的措辞不正确。

我有一个类,我在构造函数中创建一个 HashMap(下面的代码):

导入 java.util.HashMap; 导入 java.util.ArrayList;

类嬉皮扩展客户{

Hippie() {
    name = "Hippie";

    HashMap<String, Double> preferences = new HashMap<String,Double>();
    preferences.put("Donuts", 1.5);
    preferences.put("Biscotti", 0.5);

}

}

不幸的是,当我在上面创建“Hippie”对象的实例时,即使构造函数成功完成,对实例对象中 HashMap 的任何引用都会返回 null。

公共类 SEJavaDemo{ public static void main(String[] args){

Hippie Billy = new Hippie();
System.out.println(Billy.preferences);
System.out.println(Billy.name);

}

}

例如上面的代码打印出来:

空 嬉皮士

我的最终目标是能够访问由 Hippie 构造函数创建的 HashMap。任何关于它为什么返回 null 而不是 HashMap 的见解将不胜感激。谢谢!

【问题讨论】:

  • 在你的构造函数中,preferences 是一个局部变量。

标签: java constructor hashmap


【解决方案1】:
class Hippie extends Customer {

    public HashMap<String, Double> preferences;

    Hippie() {
        name = "Hippie";
        preferences = new HashMap<String,Double>();
    }
}

preferences 对外部类不可见,因为它是在您的 constructor 中创建的。您需要将其声明为实例变量,然后在构造函数中对其进行初始化,使其对外部类可见。

name 也是如此。

虽然这可能会解决您的问题,但建议您这样做:-

class Hippie extends Customer {

        private HashMap<String, Double> preferences

        Hippie() {
            name = "Hippie";
            preferences = new HashMap<String,Double>();
        }

    // have a getter for the hashmap
    public HashMap<String,Double> getMap(){
        return preferences;
    }
}

并像这样使用它:-

Hippie billy = new Hippie(); // Couldn't digest `Billy` as object name.
System.out.println(billy.getMap()); 

【讨论】:

  • 这个答案是所述问题的正确解决方案,但我不喜欢公共地图。封装和信息隐藏在哪里?不要将此作为良好实施的示例。
  • 感谢 R.J.和达菲莫。我将尝试实现一个 get 函数来返回 HashMap,希望它会起作用。谢谢!
  • 不,也不要返回地图。这不是私人的 - 您正在为任何想要更改的人提供参考。这不是一个好的抽象。为什么有人关心你选择使用地图来实现?
【解决方案2】:

因此,您正在创建对 HashMap 的本地引用。它的范围仅限于构造函数本身。为其创建一个实例变量并尝试在构造函数中填充它。它会起作用的。

【讨论】:

    【解决方案3】:

    这个设计伤了我的眼睛。

    地球上没有理由在这里使用扩展。 IS-A Hippie 总是 Customer?不是所有Customers 都有偏好吗?

    根本没有封装或信息隐藏。如果你一定要写这个,你可以这样想:

    public class Customer {
        private Map<String, Double> preferences; 
    
        public Customer() {
            this.preferences = new LinkedHashMap<String, Double>();
        }
    
        public Double getPreference(String key) {
            return this.preferences.get(key);
        }
    
        public void setPreference(String key, Double value) {
            this.preferences.put(key, value);
        }
    
        public void removePreference(String key) {
           this.preferences.remove(key);
        }
    
        public boolean hasPreference(String key) {
            return this.preferences.containsKey(key);
        }
    
        // ONLY if you must.
        public Map<String, Double> getMap() {
            return Collections.unmodifiableMap(this.preferences); 
        }
    }
    

    【讨论】:

    • 沿着这些相同的封装/信息隐藏行,getMap() 可以替换为获取地图的 keySet。这将允许其他人查看存在哪些键,但会通过您的其他方法强制它们返回以实际与数据交互。如果您想向 get/set/remove 方法添加额外的逻辑,这可能特别有价值。
    猜你喜欢
    • 2011-12-29
    • 1970-01-01
    • 2017-03-28
    • 2021-03-05
    • 2017-03-28
    • 1970-01-01
    • 1970-01-01
    • 2020-11-11
    • 2015-10-08
    相关资源
    最近更新 更多