【问题标题】:How to create map[String,Class] and create its object dynamically in scala如何在 scala 中创建 map[String,Class] 并动态创建其对象
【发布时间】:2019-03-29 00:46:39
【问题描述】:

场景: 我有一个场景,我需要一个一个地调用处理器类,这是用户输入提供者所需要的,如果没有提供,它应该调用其中的所有处理器类和 process() 方法。

代码:

class OneProcessor{}
class TwoProcessor{}

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

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

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

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

如何在scala 中做到这一点?

【问题讨论】:

    标签: scala apache-spark cassandra-3.0


    【解决方案1】:

    这是我的解决方案:

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

    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 创建保留插入顺序的映射。

    【讨论】:

    • 非常感谢先生,太棒了......让我试试并更新你。
    • 先生,还有一个问题,如果我的派生类对象定义了很多方法,我需要在特定派生对象上调用特定方法,由用户提供键,然后如何从映射中获取特定类对象并调用它的方法?
    • trait XTrait{ def show (x:String) : Unit } 类一扩展 XTrait{ def show(x:String ) = println("in class One x :" + x) } 类二扩展XTrait{ def show(x:String ) = println("in class two x :" + x) }
    • object ObjectMapper { def main(args: Array[String]) { val objMap: Map[String,XTrait] = Map( "one" -> new One(), "two" -> new Two() ) objMap.keys.foreach( key => { val obj:Option[XTrait] = objMap.get(key); /// 它不是直接转换成 XTrait . obj. /// 这不是给 show调用方法.....怎么办???我在这里做错了什么})}
    • val obj:Option[XTrait] = objMap.get(key); /// 它不是直接转换成XTrait。
    【解决方案2】:

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

    classOf[OneProcessor].newInstance
    

    【讨论】:

    • @sir 我如何从地图值中知道对象是 OneProcessor 或 TwoProcessor 来调用 classOf ?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-31
    • 2011-02-16
    • 1970-01-01
    相关资源
    最近更新 更多