关于java:创建一个可以采用多种不同模型类型的通用对象

Creating a generic object that can take on several different model types

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

本质上,我需要的是C++中的一个空指针。可以采用各种类型的东西,它们都可以执行类似的功能。我尝试使用泛型对象类,但发现它无法强制转换为正确的类型(我遇到了"不兼容的类型"错误)。

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

谢谢,-莫拉格


你的意思是这样的吗?

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

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

请注意,这个通配符有一定的限制。例如,您不能向List添加任何内容。

有关更多信息,请参阅官方教程或Angelikalanger Generics常见问题解答。


可以使用超类Classifier作为任何分类器对象的类型声明,即使每个对象都是Classifier的子类,如J48。因为它们都实现了超类的函数,所以函数调用是定义的,即使您不一定知道您使用的是哪种特定类型的分类器。axcdnt的答案与多态性的更多细节有联系。不管怎样,我有一个使用以下代码截图的工作程序;它们完全按照您的需要来做。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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();
//...

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

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

(target是一个字符串,包含从中加载模型的文件路径),如您所见,除了在创建时,当我必须指定的时候,它与我使用的分类器类型无关。注意:仍然存在一些限制,例如J48不能预测数值类。


I am currently writing a program using Weka that builds a model (using one of the various model types included in Weka). The part I'm having trouble with is that I want to allow the program to use multiple types for the same function. For example, if I choose to use a J48 decision tree, I need to build and call functions on a variable of type J48. On the other hand, if I want to use a BayesNet I need to build and call the same functions on a variable of type BayesNet. This model needs to be used at different points of the program, and so a simple if-else chain won't do.

实际上,你真正需要的是一种多态行为。请查看我回答的关于多态性的解释。

在理解了多态性背后的思想之后,深入研究并寻找工厂模式。以下是Java模式的好资源:

源生成模式

维基百科-工厂模式