简体   繁体   English

在Java中使用Scala列表和枚举

[英]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: Java代码:

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". 我收到错误消息“构造函数Foo(Enumeration.Value,List)未定义”。

how can i instantiate a new object from type Foo (with a non-empty list)? 我如何从Foo类型(带有非空列表)实例化一个新对象? Thanks in advance. 提前致谢。

Here is how you can do this 这是你可以做到的

scala file: Scala文件:

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: Java文件:

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. 在Java中使用Scala可能会很麻烦,尤其是在将scala集合放入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. 请注意,按照惯例,您应该使用大写字母开头类的名称,并且不应该为案例类的字段添加val ,因为无论如何它们都是隐式添加的。

Edit 编辑

To answer the comment, I extended Foo with sum method for test. 为了回答评论,我用sum方法扩展了Foo以进行测试。

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 . 您正在正确地进行转换,但是从javas的角度来看, Foo需要List<Object> ,因此您需要ArrayList包含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. 因此,从ArrayList<Integer>ArrayList<Object>我认为您需要创建一个新的ArrayList<Object>并读取所有元素。 As I said earlier very dirty stuff. 正如我之前说的,很脏的东西。 Better just create a scala wrapper that takes java type and converts and delegates the list. 最好只是创建一个使用Java类型并转换和委派列表的Scala包装器。

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. 我只是使用scala 2.11.8创建了2个文件的sbt项目,然后进行了编译。

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. 它会让您仅通过Java传递ArrayList<Integer>

The Scala enumeration is an object . Scala枚举是一个object Like any object it can be used from Java using the suffix $.MODULE$ 像任何object一样,它可以在Java中使用后缀$.MODULE$

TypeEnum$.MODULE$.A()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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