Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

A Java 8 (and up) compatibility kit for Scala.

License

NotificationsYou must be signed in to change notification settings

scala/scala-java8-compat

Repository files navigation

A Java 8 compatibility kit for Scala 2.12 and 2.11.

Javadoc ishere.

Do you need this?

If you are using Scala 2.13 or newer only, then don't use this library! Use the classes underscala.jdk instead; they were added to the standard library in 2.13.

We do publish 2.13 and 3.0 artifacts of scala-java8-compat, but they're only intended to be used in projects which crossbuild with 2.12 and/or 2.11.

Maintenance status

This library is community-maintained. (The Scala team at Akka provides infrastructure and oversight.)

Functional Interfaces for Scala functions

A set ofFunctional Interfacesforscala.FunctionN. These are designed for convenient construction of Scala functionsusing Java 8 lambda syntax.

Usage

importscala.concurrent.*;importstaticscala.compat.java8.JFunction.*;classTest {privatestaticFuture<Integer>futureExample(Future<String>future,ExecutionContextec) {returnfuture.map(func(s ->s.toUpperCase()),ec).map(func(s ->s.length()),ec);}}

More Examples / Documentation

Converters betweenscala.FunctionN andjava.util.function

A set of converters that enable interconversion between Java's standardFunctional Interfaces defined injava.util.function and Scala'sFunction0,Function1, andFunction2 traits. These are intended for use when youalready have an instance of ajava.util.function and need a Scala function,or have a Scala function and need an instance of ajava.util.function.

The.asScala extension method will convert ajava.util.function to the correspondingScala function. The.asJava extension method will convert a Scala function tothe most specific corresponding Java functional interface. If you wish to obtaina less specific functional interface, there are named methods that start withasJavaand continue with the name of the Java functional interface. For instance, themost specific interface corresponding to the Scala functionval rev = (s: String) => s.reverseisUnaryOperator[String], and that is whatrev.asJava will produce. However,asJavaFunction(rev) will return ajava.util.function.Function[String, String] instead.

TheasJava methods can also be called conveniently from Java. There are additionalasScalaFrom methods (e.g.asScalaFromUnaryOperator) that will perform thefunctional-interface-to-Scala-function conversion; this is primarily of use when callingfrom Java since the.asScala extension method is more convenient in Scala.

Usage examples

In Scala:

importjava.util.function._importscala.compat.java8.FunctionConverters._valfoo:Int=>Boolean= i=> i>7deftestBig(ip:IntPredicate)= ip.test(9)println(testBig(foo.asJava))// Prints truevalbar=newUnaryOperator[String]{defapply(s:String)= s.reverse }List("cod","herring").map(bar.asScala)// List("doc", "gnirrih")deftestA[A](p:Predicate[A])(a:A)= p.test(a)println(testA(asJavaPredicate(foo))(4))// Prints false// println(testA(foo.asJava)(4))  <-- doesn't work//                                    IntPredicate does not extend Predicate!

In Java:

importjava.util.function.*;importscala.compat.java8.FunctionConverters;classExample {Stringfoo(UnaryOperator<String>f) {returnf.apply("halibut");  }Stringbar(scala.Function1<String,String>f) {returnfoo(functionConverters.asJavaUnaryOperator(f));  }Stringbaz(Function<String,String>f) {returnbar(functionConverters.asScalaFromFunction(f));  }}

Converters betweenscala.concurrent andjava.util.concurrent

Conversion between Java's concurrency primitives (CompletionStage andCompletableFuture) and the Scala concurrency primitives (Promise andFuture) is enabled withscala.compat.java8.FutureConverters singleton object:

Converters betweenscala.Option andjava.util classesOptional,OptionalDouble,OptionalInt, andOptionalLong.

A set of extension methods to enable explicit conversion betweenScala Option and the Java 8optional types,Optional,OptionalDouble,OptionalInt,andOptionalLong.

Note that the four Java classes have no inheritance relationship despite all encoding optional types.

Usage example

importscala.compat.java8.OptionConverters._classTest {valo=Option(2.7)valoj= o.asJava// Optional[Double]valojd= o.asPrimitive// OptionalDoublevalojds= ojd.asScala// Option(2.7) again}

Converters from Scala collections to Java 8 Streams

Scala collections gainseqStream andparStream as extension methods that produce a Java 8 Streamrunning sequentially or in parallel, respectively. These are automatically specialized to a primitivetype if possible, including automatically applied widening conversions. For instance,List(1,2).seqStreamproduces anIntStream, and so doesList(1.toShort, 2.toShort).parStream. Maps additionally haveseqKeyStream,seqValueStream,parKeyStream, andparValueStream methods.

Scala collections also gainaccumulate andstepper methods that produce utility collections thatcan be useful when working with Java 8 Streams.accumulate produces anAccumulator or its primitivecounterpart (DoubleAccumulator, etc.), which is a low-level collection designed for efficient collectionand dispatching of results to and from Streams. Unlike most collections, it can contain more thanInt.MaxValue elements.

stepper produces aStepper which is a fusion ofSpliterator andIterator.Steppers underlie the Scalacollections' instances of Java 8 Streams. Steppers are intended as low-level building blocks for streams.Usually you would not create them directly or call their methods but you can implement them alongside customcollections to get better performance when streaming from these collections.

Java 8 Streams gaintoScala[Coll] andaccumulate methods, to make it easy to produce Scala collectionsor Accumulators, respectively, from Java 8 Streams. For instance,myStream.to[Vector] will collect thecontents of a Stream into ascala.collection.immutable.Vector. Note that standard sequential buildersare used for collections, so this is best done to gather the results of an expensive computation.

Finally, there is a Java class,ScalaStreamSupport, that has a series ofstream methods that can be used toobtain Java 8 Streams from Scala collections from within Java.

Performance Considerations

For sequential operations, Scala'siterator almost always equals or exceeds the performance of a Java 8 stream. Thus,one should favoriterator (and its richer set of operations) overseqStream for general use. However, longchains of processing of primitive types can sometimes benefit from the manually specialized methods inDoubleStream,IntStream, andLongStream.

Note that althoughiterator typically has superior performance in a sequential context, the advantage is modest(usually less than 50% higher throughput foriterator).

For parallel operations,parStream and evenseqStream.parallel meets or exceeds the performance of Scala parallelcollections methods (invoked with.par). Especially for small collections, the difference can be substantial. Insome cases, when a Scala (parallel) collection is the ultimate result, Scala parallel collections can have an advantageas the collection can (in some cases) be built in parallel.

Because the wrappers are invoked based on the static type of the collection, there are also cases where parallelizationis inefficient when interfacing with Java 8 Streams (e.g. when a collection is typed asSeq[String] so might have linearaccess likeList, but actually is aWrappedArray[String] (ArraySeq on 2.13) that can be efficiently parallelized) but can be efficientwith Scala parallel collections. TheparStream method is only available when the static type is known to be compatiblewith rapid parallel operation;seqStream can be parallelized by using.parallel, but may or may not be efficient.

If the operations available on Java 8 Streams are sufficient, the collection type is known statically with enough precisionto enable parStream, and anAccumulator or non-collection type is an acceptable result, Java 8 Streams will essentiallyalways outperform the Scala parallel collections.

Scala Usage Example

importscala.compat.java8.StreamConverters._objectTest {valm= collection.immutable.HashMap("fish"->2,"bird"->4)vals= m.parValueStream.sum// 6, potientially computed in parallelvalt= m.seqKeyStream.toScala[List]// List("fish", "bird")vala= m.accumulate// Accumulator[(String, Int)]valn= a.stepper.fold(0)(_+ _._1.length)+          a.parStream.count// 8 + 2 = 10valb= java.util.Arrays.stream(Array(2L,3L,4L)).          accumulate// LongAccumulatorvall= b.to[List]// List(2L, 3L, 4L)}

Using Java 8 Streams with Scala Function Converters

Scala can emit Java SAMs for lambda expressions that are arguments to methods that take a Java SAM rather thana Scala Function. However, it can be convenient to restrict the SAM interface to interactions with Java code(including Java 8 Streams) rather than having it propagate throughout Scala code.

Using Java 8 Stream converters together with function converters allows one to accomplish this with only a modestamount of fuss.

Example:

importscala.compat.java8.FunctionConverters._importscala.compat.java8.StreamConverters._defmapToSortedString[A](xs:Vector[A],f:A=>String,sep:String)=  xs.parStream.// Creates java.util.stream.Stream[String]    map[String](f.asJava).sorted.// Maps A to String and sorts (in parallel)    toArray.mkString(sep)// Back to an Array to use Scala's mkString

Note that explicit creation of a new lambda will tend to lead to improved type inference and at least equalperformance:

defmapToSortedString[A](xs:Vector[A],f:A=>String,sep:String)=  xs.parStream.    map[String](a=> f(a)).sorted.// Explicit lambda creates a SAM wrapper for f    toArray.mkString(sep)

Java Usage Example

To convert a Scala collection to a Java 8 Stream from within Java, it usuallysuffices to callScalaStreamSupport.stream(xs) on your collectionxs. Ifxs isa map, you may wish to get the keys or values alone by usingfromKeys orfromValues. If the collection has an underlying representation that is notefficiently parallelized (e.g.scala.collection.immutable.List), thenfromAccumulated (andfromAccumulatedKeys andfromAccumulatedValues) willfirst gather the collection into anAccumulator and then return a stream overthat accumulator. If not running in parallel,from is preferable (faster andless memory usage).

Note that a ScalaIterator cannot fulfill the contract of a Java 8 Stream(because it cannot supporttrySplit if it is called). Presently, one mustcallfromAccumulated on theIterator to cache it, even if the Stream willbe evaluated sequentially, or wrap it as a Java Iterator and use staticmethods inSpliterator to wrap that as aSpliterator and then aStream.

Here is an example of conversion of a Scala collection within Java 8:

importscala.collection.mutable.ArrayBuffer;importscala.compat.java8.ScalaStreamSupport;publicclassStreamConvertersExample {publicintMakeAndUseArrayBuffer() {ArrayBuffer<String>ab =newArrayBuffer<String>();ab.$plus$eq("salmon");ab.$plus$eq("herring");returnScalaStreamSupport.stream(ab).mapToInt(x ->x.length()).sum();// 6+7 = 13  }}

Converters betweenscala.concurrent.duration.FiniteDuration andjava.time.Duration

Interconversion between Java's standardjava.time.Duration typeand thescala.concurrent.duration.FiniteDuration types. The JavaDuration doesnot contain a time unit, so when converting fromFiniteDuration the time unit usedto create it is lost.

For the opposite conversion aDuration can potentially express a larger time span thanaFiniteDuration, for such cases an exception is thrown.

Example of conversions from the Java type ways:

importscala.concurrent.duration._importscala.compat.java8.DurationConverters._valjavaDuration: java.time.Duration=5.seconds.toJavavalfiniteDuration:FiniteDuration= javaDuration.toScala

From Java:

importscala.compat.java8.DurationConverters;importscala.concurrent.duration.FiniteDuration;DurationConverters.toScala(Duration.of(5,ChronoUnit.SECONDS));DurationConverters.toJava(FiniteDuration.create(5,TimeUnit.SECONDS));

About

A Java 8 (and up) compatibility kit for Scala.

Resources

License

Code of conduct

Stars

Watchers

Forks

Packages

No packages published

Contributors24


[8]ページ先頭

©2009-2025 Movatter.jp