java - 将 Java 代码转换为 Scala 代码

标签 java scala

我想将以下 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();
  }
 }

这是我所拥有的,它会导致错误:

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
}

错误:

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

我该如何解决?

最佳答案

可变参数

scala 中的 Varargs 是 Seq,而不是 Array。所以 objs 不能是 Array[MyClass1] 的实例。

实际上你可以像这样得到一个Array:

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

但是你会得到一个Array[_],而不是一个Array[MyClass1]:

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

您可以检查 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)

在这种情况下,您不需要Array:

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

list

你应该使用 Manifest这里:

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

Manifest 是类型删除的变通方法,但您不能从 Java 调用此类方法。

平面 map

Array[_] 不是 Object[]。您应该将 Array[_] 替换为 Array[Any]

使用 x.map(method2).toArray 你会得到 Array[Array[Any]]。我猜你想得到 Array[Any] (就像在你的 Java 代码中一样),所以你应该使用 flatMap 而不是 map 来聚合所有数组。

到字符串

您正在尝试将函数 toString 传递给方法 map:

x.map(toString)

没有这个功能。你必须创建一个:

x.map{e => e.toString}

或更短:

x.map{_.toString}

关于java - 将 Java 代码转换为 Scala 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17293264/

相关文章:

Java Sockets - 将文件从客户端发送到服务器

java - 从 JTextField 中删除 InputVerifier

scala - 使用 Scala 将 SparkRDD 写入 HBase 表

scala - 如何(管道)在模式匹配工作中?

java - 如何从 Java 中的文本文件中读取逗号分隔值?

java - 在按值排序的 map 中的条目周围检索固定数量的条目

scala - 在CRUD Web应用程序中使用Akka actor

scala - 如何使用 foreachPartition 在 Spark 中为每个分区高效构建一个 ML 模型?

Scala Dataframe空检查列

自动关闭资源的Java 8 Stream(基于资源).iterator()?