JavaコードをScalaコードに変換する努力の一環として、Java stream Files.walk(Paths.get(ROOT))
Scalaへ。グーグルで解決策を見つけることができません。asScala
はそれをしません。
関連するコードは次のとおりです。
_import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn;
import Java.io.IOException;
import Java.nio.file.Files;
import Java.nio.file.Paths;
import Java.util.stream.Collectors;
....
Files.walk(Paths.get(ROOT))
.filter(path -> !path.equals(Paths.get(ROOT)))
.map(path -> Paths.get(ROOT).relativize(path))
.map(path -> linkTo(methodOn(FileUploadController.class).getFile(path.toString())).withRel(path.toString()))
.collect(Collectors.toList()))
_
javaでは、Files.walk(Paths.get(ROOT))
戻り値の型は_Stream<Path>
_です。
互換性のあるレイヤーや前述の実験的な2.11の機能を必要とせずに、少し良い方法があります here by @ marcospereira
基本的にはイテレーターを使用するだけです:
import Java.nio.file.{Files, Paths}
import scala.collection.JavaConverters._
Files.list(Paths.get(".")).iterator().asScala
Java 8ストリームとScalaストリームは概念的に異なるものです。 Java 8ストリームはコレクションではないため、通常のコレクションコンバーターは機能しません。 scala-Java8-compat ( github )ライブラリを使用して、Java StreamsにtoScala
メソッドを追加できます。
import scala.compat.Java8.StreamConverters._
import Java.nio.file.{ Files, Path, Paths }
val scalaStream: Stream[Path] = Files.walk(Paths.get(".")).toScala[Stream]
Javaからこの変換(Java-> Scala)を実際に使用することはできません。したがって、Javaからこれを行う必要がある場合は、ストリームを実行してScalaストリームを構築する方が簡単です(それでも厄介です)自分(前述のライブラリが内部で行っていること):
import scala.collection.immutable.Stream$;
import scala.collection.mutable.Builder;
import Java.nio.file.Files;
import Java.nio.file.Path;
import Java.nio.file.Paths;
import Java.util.stream.Stream;
final Stream<Path> stream = Files.walk(Paths.get("."));
final Builder<Path, scala.collection.immutable.Stream<Path>> builder = Stream$.MODULE$.newBuilder();
stream.forEachOrdered(builder::$plus$eq);
final scala.collection.immutable.Stream<Path> result = builder.result();
ただし、どちらの方法でもJava Streamを完全に消費するため、Scala Streamに変換することで遅延評価の利点を得ることはできず、直接変換することもできます。ベクトルに。 Scala関数リテラル構文のみを使用する場合は、さまざまな方法でこれを実現できます。同じライブラリーを使用して、コレクションコンバーターに似た関数コンバーターを使用できます。
import scala.compat.Java8.FunctionConverters._
import Java.nio.file.{ Files, Path, Paths }
val p: Path => Boolean = p => Files.isExecutable(p)
val stream: Java.util.stream.Stream[Path] = Files.walk(Paths.get(".")).filter(p.asJava)
あるいは、2.11以降、Scalaは-Xexperimental
フラグの下でSAMタイプを実験的にサポートしています。これは、2.12でフラグなしの非実験的です。
$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_92).
Type in expressions for evaluation. Or try :help.
scala> import Java.nio.file.{ Files, Path, Paths }
import Java.nio.file.{Files, Path, Paths}
scala> Files.walk(Paths.get(".")).filter(p => Files.isExecutable(p))
<console>:13: error: missing parameter type
Files.walk(Paths.get(".")).filter(p => Files.isExecutable(p))
^
scala> :set -Xexperimental
scala> Files.walk(Paths.get(".")).filter(p => Files.isExecutable(p))
res1: Java.util.stream.Stream[Java.nio.file.Path] = Java.util.stream.ReferencePipeline$2@589838eb
scala> Files.walk(Paths.get(".")).filter(Files.isExecutable)
res2: Java.util.stream.Stream[Java.nio.file.Path] = Java.util.stream.ReferencePipeline$2@185d8b6
Scala 2.13
を開始すると、標準ライブラリには scala.jdk.StreamConverters
が含まれ、Java to Scala暗黙的なストリーム変換を提供します。
import scala.jdk.StreamConverters._
val javaStream = Files.walk(Paths.get("."))
// javaStream: Java.util.stream.Stream[Java.nio.file.Path] = Java.util.stream.ReferencePipeline$3@51b1d486
javaStream.toScala(LazyList)
// scala.collection.immutable.LazyList[Java.nio.file.Path] = LazyList(?)
javaStream.toScala(Iterator)
// Iterator[Java.nio.file.Path] = <iterator>
LazyList
sはScala 2.13
でStream
に名前が変更されているため、Stream
の使用に注意してください(LazyList
とは対照的)。