2016-07-12 26 views
9

Als Teil der Bemühungen, Java-Code in Scala-Code zu konvertieren, muss ich den Java-Stream Files.walk(Paths.get(ROOT)) in Scala konvertieren. Ich kann keine Lösung finden, indem ich googele. asScala wird es nicht tun. Irgendwelche Hinweise?Wie man einen Java-Stream in einen Scala-Stream konvertiert

Im Folgenden ist der zugehörige Code:

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())) 

wo die Files.walk (Paths.get (ROOT)) Rückgabetyp-Stream in Java ist.

+0

@NathanielFord vielleicht ein Tag für Java gibt es 8? –

+0

Was brauchst du wirklich? In 2.12 können Sie 'stream.filter (x => etwas)' '. –

+0

@ som-snytt Ich muss zuerst den Java-Stream-Typ konvertieren, bevor ich den Scala-Code anwende. – TeeKai

Antwort

6

Java 8 Streams und Scala Streams sind konzeptionell verschiedene Dinge; Der Java 8 Stream ist keine Sammlung, daher funktioniert der übliche Sammlungskonverter nicht. Sie können die scala-java8-compat (github) Bibliothek verwenden, um eine toScala Methode, um Java-Streams hinzuzufügen: kann

import scala.compat.java8.StreamConverters._ 
import java.nio.file.{ Files, Path, Paths } 

val scalaStream: Stream[Path] = Files.walk(Paths.get(".")).toScala[Stream] 

Sie nicht wirklich diese Umwandlung verwenden (Java-> Scala) aus Java, wenn Sie also tun müssen, um diese aus Java, es ist einfacher (aber immer noch umständlich) nur den Strom laufen und die Scala-Stream selbst bauen (das ist, was die zuvor erwähnte Bibliothek unter der Haube tut):

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(); 

Allerdings werden beide Möglichkeiten verbrauchen vollständig die Java Stream, so dass Sie nicht den Vorteil der Lazy-Evaluierung erhalten, indem Sie es in einen Scala-Stream umwandeln und vielleicht auch nur c direkt auf einen Vector umkehren. Wenn Sie nur die Scala-Funktionsliteralsyntax verwenden möchten, gibt es verschiedene Möglichkeiten, dies zu erreichen. Sie könnten die gleiche Bibliothek verwenden, um Funktion Wandler ähnlich Sammlung Wandler zu verwenden:

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) 

Alternativ seit 2.11, Scala hat experimentelle Unterstützung für SAM-Typen unter der -Xexperimental Flagge. Dies wird ohne eine Flagge in 2.12 nicht experimentell sein.

$ 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] = [email protected] 

scala> Files.walk(Paths.get(".")).filter(Files.isExecutable) 
res2: java.util.stream.Stream[java.nio.file.Path] = [email protected] 
11

Es gibt eine etwas schönere Art und Weise ist erwähnt die compat Schicht oder experimentelle 2.11 Funktionen, ohne dass here von @marcospereira

Im Grunde nur einen Iterator verwenden:

import java.nio.file.{Files, Paths} 
import scala.collection.JavaConverters._ 

Files.list(Paths.get(".")).iterator().asScala 
Verwandte Themen