简体   繁体   中英

Use scala List and Enumeration in Java

i couldn't find a solution for this problem:

i have this scala code

package testScala

import scala.collection.JavaConversions._
import collection.mutable._

object TypeEnum extends Enumeration {
  type TypeEnum=Value
  val A, B, C, D, E = Value
}

import TypeEnum._

case class Foo(param1: TypeEnum, param2: List[Int]) {
  def length: Int = param2.length
}

Java code:

package testJava;

import java.util.List;
import java.util.ArrayList;

import scala.collection.JavaConversions;

import testScala.TypeEnum;
import testScala.Foo;



public class testJava {
    public static void main (String[] args)
    {

        List<Object> l1 = new ArrayList<>();
        l1.add(1);
        l1.add(2);

        //Error here
        Foo f = new Foo(TypeEnum.A(), JavaConversions.asScalaBuffer(l1).toList());

    }
}

i get the error "The constructor Foo(Enumeration.Value, List) is undefined".

how can i instantiate a new object from type Foo (with a non-empty list)? Thanks in advance.

Here is how you can do this

scala file:

package test

object TypeEnum extends Enumeration {
  type TypeEnum=Value
  val A, B, C, D = Value
}

import TypeEnum._

case class Foo(param1: TypeEnum, param2: List[Int])

java file:

import scala.collection.immutable.List;
import test.TypeEnum;
import test.Foo;

public class Test {
    public static void main(String[] args) {
        Foo foo = new Foo(TypeEnum.A(), null);
        System.out.println(foo.param1());
    }
}

But maybe better don't. Using scala from java can be a pain, expecially when you put scala collections in the api.

Note that by convention you should start name of your classes with capital letter, and you shouldn't put val for fields of case classes as they are added implicitly anyway.

Edit

To answer the comment, I extended Foo with sum method for test.

case class Foo(param1: TypeEnum, param2: List[Int]) {
  def sum = param2.sum
}

You were converting it right but from javas point of view, Foo needs List<Object> , so you need your ArrayList to contain Objects .

List<Object> list = new ArrayList<>();
list.add(2);
list.add(4);
Foo foo = new Foo(TypeEnum.A(), JavaConversions.asScalaBuffer(list).toList());
System.out.println(foo.param1());
System.out.println(foo.sum());

So to get your way from ArrayList<Integer> to ArrayList<Object> I think you need to create a new ArrayList<Object> and readd all elements. As I said earlier very dirty stuff. Better just create a scala wrapper that takes java type and converts and delegates the list.

Edit

As the code you presented works for me maybe you have something else causing the problem. I simply created sbt project with 2 files, using scala 2.11.8 and it compiles.

Here is the adapter class I mentioned before

import scala.collection.JavaConverters._
class FooAdapter(param1: TypeEnum, param2: java.util.List[Integer])
  extends Foo(param1, param2.asScala.map(_.intValue).toList)

it will let you to pass just an ArrayList<Integer> from java.

The Scala enumeration is an object . Like any object it can be used from Java using the suffix $.MODULE$

TypeEnum$.MODULE$.A()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM