如何在scala中创建map [String,Class]并动态创建其对象

时间:2018-10-24 14:39:12

标签: scala apache-spark cassandra-3.0

场景:        我有一个问题,我需要一个一个地调用处理器类,这是用户输入提供程序所必需的,如果未提供,则应该调用其中的所有处理器类和process()方法。

代码:

class OneProcessor{}
class TwoProcessor{}

为此,我正在考虑创建Map [String,instanceOfClass],即:

val instanceMap:Map[String,Class] =Map(
    "string1" -> new OneProcessor(),
    "string2" -> new TwoProcessor(),
)

问题:             如果用户给定string1,则我需要创建OneProcessor()的实例并执行instance()方法。

如果未向用户提供任何输入,则需要调用Map的所有键,并创建所有类的实例并调用所有类的processor()...

如何在scala中执行此操作?

2 个答案:

答案 0 :(得分:0)

您可以调用newInstance方法来创建类外的实例。

classOf[OneProcessor].newInstance

答案 1 :(得分:0)

这是我的解决方法:

假设所有“处理器”都在做类似的事情,我建议从特征中扩展它们,而不是使用通用的类级构造。让我们假设以下结构:

trait Processor {
  def process=println("default process")
}
case class ProcessorOne() extends Processor
case class ProcessorTwo() extends Processor {
  override def process=println("process 2")
}
case class ProcessorThree() extends Processor {
  override def process=println("process 3")
}

我们创建一个地图,并将所有process函数放入其中:

val myFuncs =
  Map("string1" -> (() => ProcessorOne().process),
    "string2" -> (() => ProcessorTwo().process),
  "string3" -> (() => ProcessorThree().process))

请注意,这是一个Map[String, Unit]。由于您的目标是调用函数,因此您实际上不需要在地图中放置实例。

现在您可以轻松地调用任何或所有这些功能:

val userInput =""

if(myFuncs isDefinedAt userInput)
  myFuncs(userInput)()
else
  myFuncs.values.foreach(v => v())

以上将输出:

default process
process 2
process 3

因此,如果键不存在于映射中,则将调用所有功能(不按特定顺序),但是,如果键位于映射中,则仅将调用与该键关联的功能。

如果您还需要按特定顺序运行这些功能,则可以使用LinkedHasMapListMap创建一个保留插入顺序的映射。