簡體   English   中英

在Scala中平面映射Java列表

[英]Flatmap a Java list in Scala

我有一個簡化的定義的Java接口

public interface JavaInterface {
  List<? extends Foo> getFoos()
}

public interface Foo {
  List<? extends Bar> getBars()
}

public interface Bar { }

在scala中,我試圖對列表進行flatMap ,並得到有關scala.collection.mutable.Bufferscala.collection.GenTraversableOnce不匹配的錯誤。 看來Buffer確實擴展了GenTraversableOnce ,所以我認為問題與使通用參數對齊有關。

我可以通過以下Scala代碼獲得相同的編譯錯誤:

import java.util._
import java.util.{List => JList}
import scala.collection.JavaConverters._

trait Base {
    def anotherList: JList[_ <: Base]
}

trait Derived extends Base {}


class Sample
{
    def aList: JList[_ <: Base] = new ArrayList[Base]()

    val foo = aList.asScala.flatMap(_.anotherList.asScala)
}

失敗為

[info] Compiling 1 Scala source to /Users/test/scala/target/scala-2.12/classes ...
[error] /Users/test/scala/src/main/scala/Test.scala:16:25: no type parameters for method flatMap: (f: _$2 => scala.collection.GenTraversableOnce[B])(implicit bf: scala.collection.generic.CanBuildFrom[scala.collection.mutable.Buffer[_$2],B,That])That exist so that it can be applied to arguments (_$2 => scala.collection.mutable.Buffer[_ <: Base])
[error]  --- because ---
[error] argument expression's type is not compatible with formal parameter type;
[error]  found   : _$2 => scala.collection.mutable.Buffer[_ <: Base] where type _$2 <: Base
[error]  required: _$2 => scala.collection.GenTraversableOnce[?B] where type _$2 <: Base
[error] val foo = aList.asScala.flatMap(_.anotherList.asScala)
[error]                         ^
[error] /Users/test/scala/src/main/scala/Test.scala:16:47: type mismatch;
[error]  found   : _$2 => scala.collection.mutable.Buffer[_ <: Base] where type _$2 <: Base
[error]  required: _$2 => scala.collection.GenTraversableOnce[B] where type _$2 <: Base
[error] val foo = aList.asScala.flatMap(_.anotherList.asScala)
[error]                                               ^
[error] /Users/test/scala/src/main/scala/Test.scala:16:32: Cannot construct a collection of type That with elements of type B based on a collection of type scala.collection.mutable.Buffer[_$2].
[error] val foo = aList.asScala.flatMap(_.anotherList.asScala)
[error]                                ^
[error] three errors found
[error] (Compile / compileIncremental) Compilation failed
[error] Total time: 1 s, completed Aug 28, 2019, 5:11:29 PM

我究竟做錯了什么?

我猜這被認為是Scala中的錯誤,而不是您的代碼,因為您的代碼在2.13中可以正常編譯。 這似乎是Scala Buffers與Java Lists如何處理差異之間的差異的結果。 我認為最簡單的解決方法是在flatMap使用像Scala List這樣的協變集合,例如:

aList.asScala.flatMap(_.anotherList.asScala.toList)

您還可以使類型參數不變,例如:

aList.asScala.flatMap(_.anotherList.asScala.asInstanceOf[Buffer[Base]])

要么

aList.asScala.map(_.anotherList.asScala).flatten[Base]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM