创建可以采用多种不同模型类型的通用对象

时间:2012-07-04 18:15:43

标签: java generics weka

我目前正在使用Weka编写程序来构建模型(使用Weka中包含的各种模型类型之一)。我遇到麻烦的部分是我想让程序为同一个函数使用多种类型。例如,如果我选择使用J48决策树,我需要在J48类型的变量上构建和调用函数。另一方面,如果我想使用BayesNet,我需要在BayesNet类型的变量上构建和调用相同的函数。这个模型需要在程序的不同点使用,因此一个简单的if-else链不会这样做。

基本上我需要的是相当于C ++中的void指针。可以采用各种类型的东西,可以执行类似的功能。我尝试使用通用的Object类,但发现无法将其转换为正确的类型(我遇到了“不兼容的类型”错误)。

所以,我的问题的简短版本是:Java程序员如何解决C ++程序员用void指针解决的问题?

谢谢, -Morag

3 个答案:

答案 0 :(得分:3)

你是说,是这样的吗?

public void doStuff(MyType<?> someObject) { }  

?代表任何类型,代表unbounded wildcard

请注意,这个通配符有一定的局限性。例如,您无法向List<?>添加任何内容。

有关详细信息,请参阅Official TutorialAngelikaLanger Generics FAQ

答案 1 :(得分:0)

  

我目前正在使用Weka编写一个程序来构建一个模型(使用Weka中包含的各种模型类型之一)。我遇到麻烦的部分是我想让程序为同一个函数使用多种类型。例如,如果我选择使用J48决策树,我需要在J48类型的变量上构建和调用函数。另一方面,如果我想使用BayesNet,我需要在BayesNet类型的变量上构建和调用相同的函数。这个模型需要在程序的不同点使用,因此一个简单的if-else链不会

实际上你真正需要的是多态行为。请查看这篇文章,我回答了一些问题:Polymorphism

在理解了多态性背后的想法之后,去深入了解并寻找工厂模式。以下是Java模式的优秀资源:

Source Making Patterns

Wikipedia - Factory Pattern

答案 2 :(得分:0)

您可以使用超类Classifier作为任何分类器对象的类型声明,即使每个对象都是Classifier的子类,例如J48。它的工作原理是因为它们都实现了超类的功能,因此即使您不一定知道正在使用哪种特定类型的分类器,也会定义函数调用。 Axcdnt的答案提供了有关多态性的更多细节的链接。无论如何,我有一个带有以下代码snippits的工作程序;他们完全按照您的需要行事。

Classifier Clfs = null;

    try {
        if (modelType.equals("J48")) {
            Clfs = new J48();
        } else if (modelType.equals("MLP")) {
            Clfs = new MultilayerPerceptron(); 
        } else if (modelType.equals("IB3")) {
            Clfs = new IBk(3);
        } else if (modelType.equals("RF")) {
            Clfs = new RandomForest(); 
        } else if (modelType.equals("NB")) {
            Clfs = new NaiveBayes();
//...

和其他地方,在将分类器写入我调用的文件

之后
Classifier cls = (Classifier) weka.core.SerializationHelper.read(target);
prediction = cls.distributionForInstance(data.instance(0));

target是一个包含从中加载模型的文件路径的字符串。正如您所看到的,除了在创建时,我必须指定时,我使用的分类器类型无关紧要。注:仍然会有一些限制,例如j48无法预测数字类。