2016-07-12 13 views
9

W ramach próby konwersji kodu Java na kod Scala, muszę przekonwertować strumień Java Files.walk(Paths.get(ROOT)) na Scalę. Nie mogę znaleźć rozwiązania, korzystając z googlowania. asScala nie zrobi tego. Jakieś wskazówki?Jak konwertować strumień Java do strumienia Scala

Poniższe jest powiązany Kod:

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

gdzie Files.walk (Paths.get (Root)) Typ zwrotny jest strumień Java.

+0

@NathanielFord Może jest tag for Java 8? –

+0

Czego naprawdę potrzebujesz? W 2.12 możesz 'stream.filter (x => coś)'. –

+0

@ som-snytt Muszę najpierw przekonwertować typ strumienia Java przed zastosowaniem kodu Scala. – TeeKai

Odpowiedz

6

Strumienie Java 8 i Scala są koncepcyjnie różnymi rzeczami; Java 8 Stream nie jest kolekcją, więc zwykły konwerter kolekcji nie będzie działał. Można użyć (github) biblioteka scala-java8-compat dodać metodę toScala Java Streams:

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

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

Naprawdę nie można użyć tej konwersji (Java-> Scala) z Java, więc jeśli masz to zrobić od Java, łatwiej (ale nadal niewygodne) w celu wystarczy uruchomić strumień i budować SCALA Stream siebie (co jest co wspomniana biblioteka robi pod maską):

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

jednak obie strony będą w pełni konsumować Java Strumień, dzięki czemu nie uzyskasz korzyści z leniwego oszacowania, konwertując go do strumienia Scala i równie dobrze może on po prostu c zamień go bezpośrednio na wektor. Jeśli chcesz tylko użyć dosłownej składni funkcji Scala, istnieją różne sposoby osiągnięcia tego. Można użyć tej samej biblioteki użyć konwerterów funkcyjnych, podobne do konwerterów kolekcji:

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) 

Ewentualnie od 2.11, Scala ma eksperymentalne wsparcie dla typów SAM pod flagą -Xexperimental. To będzie nieeksperymentalne bez flagi w 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] = [email protected] 

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

Jest nieco ładniejszy sposób bez potrzeby z kompatybilnego warstwę lub eksperymentalne 2.11 wymienionych here przez @marcospereira możliwości

Zasadniczo wystarczy użyć iterator:

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

Files.list(Paths.get(".")).iterator().asScala 
Powiązane problemy