简体   繁体   English

将Java代码转换为Scala代码

[英]Converting Java code to Scala code

I want to convert the following Java code to Scala one: 我想将以下Java代码转换为Scala之一:

Object method1(Object ... objArray) {
  if (objArray instanceof MyClass1[]) {
      Object resArray[] = new Object[objArray.length];
      for (int i = 0; i < objArray.length; i++) {
        resArray[i] = objArray[i].toString();
      }
      return resArray;
    } else {
      List<Object> resArray = new ArrayList<Object>();
      for (int i = 0; i < objArray.length; i++) {
        for (Object obj: scalar(objArray[i])) {
          resArray.add(obj);
        }
      }
      return resArray.toArray();
    }
  }

  //..........
  private static class MyClass1 {       
  private Object obj;

  public MyClass1(Object obj) {
    this.obj = obj;
  }

  @Override
  public String toString() {
    return obj.toString();
  }
 }

Here is what I have and it causes the errors: 这是我所拥有的,它会导致错误:

def method1(objs: Any*): Array[_] = objs match {
    case x: Array[MyClass1] => x.map(toString)  // MyClass1 looks like 
    case x => x.map(method2).toArray
  }

//...................
def method2(obj: Any): Array[_] = {....} //it's perfectly fine

class MyClass1 (obj: AnyRef) {
    override def toString = obj.toString
}

errors: 错误:

1)pattern type is incompatible with expected type;
[error]  found   : Array[MyClass1]
[error]  required: Any*
[error]     case x: Array[MyClass1] => x.map(toString)

2)type mismatch;
[error]  found   : Array[MyClass1]
[error]  required: Any*
[error]     case x: Array[MyClass1] => x.map(toString)

3)could not find implicit value for evidence parameter of type ClassManifest[Array[_]]
[error]     case x => x.map(method2).toArray

How do I solve this? 我该如何解决?

Varargs 瓦拉格斯

Varargs in scala is Seq , not Array . Scala中的Varargs是Seq ,而不是Array So objs can't be an instance of Array[MyClass1] . 所以objs不能实例Array[MyClass1]

Actually you could get an Array like this: 实际上,您可以获得这样的Array

def test(s: Any*) = s match {
  case wa: WrappedArray[_] => wa.array
  case _ => ???
}

But you'll get an Array[_] , not an Array[MyClass1] : 但是您会得到一个Array[_] ,而不是Array[MyClass1]

scala> test("a", "b", "c").isInstanceOf[Array[String]]
res0: Boolean = false

You could check all elements of Array and then convert Array[_] to Array[MyClass1] , but I don't think it's what you want: 您可以检查Array所有元素,然后将Array[_]转换为Array[MyClass1] ,但我认为这不是您想要的:

scala> test("a", "b", "c") match {
     |   case a if a.forall{_.isInstanceOf[String]} => a.map{ case s: String => s }
     | }
res1: Array[String] = Array(a, b, c)

In this case you don't need an Array : 在这种情况下,您不需要Array

def method1(objs: Any*): Array[_] = objs match {
  case x if x.forall{_.isInstanceOf[MyClass1]} => x.map{_.toString}.toArray
  ...
}

Manifest 表现

You should use Manifest here: 您应该在此处使用Manifest

def test[T: Manifest](es: T*) = {
  if (implicitly[Manifest[T]] <:< implicitly[Manifest[MyClass1]])
    es.map{_.toString}.toArray
  else 
    x.flatMap(method2).toArray
}

Manifest is a workaround for type erasure, but you can't call such methods from Java . Manifest是解决类型擦除的一种解决方法,但是您不能从Java调用此类方法。

flatMap flatMap

Array[_] is not a Object[] . Array[_]不是Object[] You should replace Array[_] with Array[Any] . 您应该将Array[_]替换为Array[Any]

With x.map(method2).toArray you'll get Array[Array[Any]] . 使用x.map(method2).toArray您将获得Array[Array[Any]] I guess you want to get Array[Any] (as in your Java code), so you should use flatMap instead of map to aggregate all arrays. 我想您想获取Array[Any] (如您的Java代码一样),因此您应该使用flatMap而不是map来聚合所有数组。

toString toString

You are trying to pass function toString to method map : 您正在尝试将toString函数传递给方法map

x.map(toString)

There is no such function. 没有这种功能。 You have to create one: 您必须创建一个:

x.map{e => e.toString}

Or shorter: 或更短:

x.map{_.toString}

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

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