Scala Java Error: value filter is not a member of

2019-04-18 08:16发布

问题:

I'm trying to refactor some Scala code in Eclipse and run into this compilation error:

value filter is not a member of java.util.Map

import java.io.File
import com.typesafe.config._

class ConfigLoader  {

    def parseFile( confFile : File) {
        val conf = ConfigFactory.parseFile(confFile).root().unwrapped();        
        for((k,v) <- conf; (dk, dv) = (k, v.toString())) config.param += (dk -> dv);        
    }

(config is an object with "param" being a Map of String:String)

This code was pull exactly from Main() where it worked fine like so:

object Main extends Logging {        

    def main(args: Array[String]) {
        //code cropped for readability. 
        //config.param["properties"] is absolute path to a passed-in properties file. 

        val conf = ConfigFactory.parseFile(new java.io.File(config.param("properties"))).root().unwrapped();

        for((k,v) <- conf; (dk, dv) = (k, v.toString())) config.param+=(dk -> dv);

as you can see the code is exactly the same. I've imported the same libraries. All i'm doing different in main now is instantiating ConfigLoader and calling it like so:

cfgLoader.parseFile(config.param("properties"))

Any ideas what's causing the error just by moving it to a class?

I've googled the error and it seems to be pretty generic.

回答1:

Turns out I was missing a tricky import after all:

import collection.JavaConversions._

not to be confused with JavaConverters._ which I did have.

Hope this helps someone else.



回答2:

The problem is that you are using a java Map which doesn't implement the monad api (map, flatMap, ...) required to use scala for-comprehension.

More specifically, in your example, the compiler is complaining about missing .filter method. This is because you unpack each item of the map: (key, value) <- monad instead of a direct assignment, such as entry <- monad. But even if you did use direct assignment, it would complain about missing .map or .flatMap. See this answer to "how to make you own for-comprehension compliant scala monad for details on the required api.

The simplest solution to your problem is to convert you java map into scala map using:

import scala.collection.JavaConverters._

...
for((k,v) <- conf.asScala) ...

The import includes implicit that add the .asScala method to java map