我是java的新手,通过创建一个简单的NaiveBayes分类器来练习。我仍然是对象实例化的新手,并想知道如何初始化HashMaps的HashMap。在将新观察值插入分类器时,我可以为给定类中看不见的特征名创建一个新的HashMap,但是我是否需要初始化?
import java.util.HashMap;
public class NaiveBayes {
private HashMap<String, Integer> class_counts;
private HashMap<String, HashMap<String, Integer>> class_feature_counts;
public NaiveBayes() {
class_counts = new HashMap<String, Integer>();
// do I need to initialize class_feature_counts?
}
public void insert() {
// todo
// I think I can create new hashmaps on the fly here for class_feature_counts
}
public String classify() {
// stub
return "";
}
// Naive Scoring:
// p( c | f_1, ... f_n) =~ p(c) * p(f_1|c) ... * p(f_n|c)
private double get_score(String category, HashMap features) {
// stub
return 0.0;
}
public static void main(String[] args) {
NaiveBayes bayes = new NaiveBayes();
// todo
}
}
请注意,这个问题并不是针对Naive Bayes分类器的,因为我想提供一些上下文。
答案 0 :(得分:20)
是的,你需要初始化它。
class_feature_counts = new HashMap<String, HashMap<String, Integer>>();
如果要为class_feature_counts添加值,还需要实例化它:
HashMap<String, Integer> val = new HashMap<String, Integer>();
// Do what you want to do with val
class_feature_counts.put("myKey", val);
答案 1 :(得分:11)
递归通用数据结构,如地图地图,虽然不是一个彻头彻尾的坏主意,但往往表明你可以重构的东西 - 内部地图通常可能是一阶对象(它拥有一张地图),而不仅仅是一个地图。你仍然需要初始化这些内部对象,但它通常是一种更清洁,更清晰的开发方式。
例如,如果您有一个Map<A,Map<B,C>>
,那么您经常会将A的地图存储到Thing中,但Thing的存储方式恰好是一张地图。你经常会发现它更清晰,更容易隐藏Thing是一个地图的事实,而是存储Map<A,Thing>
的映射,其中的东西被定义为:
public class Thing {
// Map is guaranteed to be initialized if a Thing exists
private Map<B,C> data = new Map<B,C>();
// operations on data, like get and put
// now can have sanity checks you couldn't enforce when the map was public
}
另外,查看Guava的Mulitmap/Multiset实用程序,它们对于这样的情况非常有用,特别是它们会自动执行内部对象初始化。对于你的情况,几乎在任何时候你实现Map<E, Integer>
你真的想要一个Guava Multiset。更清洁,更清晰。
答案 2 :(得分:2)
您必须创建对象,然后才能通过引用变量使用它。这个对象有多复杂并不重要。您不需要在构造函数中初始化它,尽管这是最常见的情况。根据您的需要,您可能希望使用“延迟初始化”。
答案 3 :(得分:2)
HashMap
声明您的变量。这太有限了。是的,您需要初始化class_feature_counts
。您将添加条目,因此它必须是有效的地图。实际上,在声明而不是构造函数中初始化它们,因为每个启动只有一种方法。我希望你现在正在使用Java 7;这种方式更简单。
私人地图&lt;字符串,整数&gt; classCounts = new HashMap&lt;&gt;();
私人地图&lt;字符串,地图&lt;字符串,整数&gt;&gt; classFeatureCounts = new HashMap&lt;&gt;();
编译器将从&lt;&gt;中推断出类型。此外,我将变量名称更改为标准Java驼峰式样式。 classCounts
和classFeatureCounts
是否已关联?