• Stars
    star
    436
  • Rank 99,877 (Top 2 %)
  • Language
    Scala
  • License
    Apache License 2.0
  • Created over 10 years ago
  • Updated 8 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

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

scala-java8-compat

A Java 8 compatibility kit for Scala 2.12 and 2.11.

Javadoc is here.

Do you need this?

If you are using Scala 2.13 or newer only, then don't use this library! Use the classes under scala.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 Lightbend provides infrastructure and oversight.)

Functional Interfaces for Scala functions

A set of Functional Interfaces for scala.FunctionN. These are designed for convenient construction of Scala functions using Java 8 lambda syntax.

Usage

import scala.concurrent.*;
import static scala.compat.java8.JFunction.*;

class Test {
	private static Future<Integer> futureExample(Future<String> future, ExecutionContext ec) {
	    return future.map(func(s -> s.toUpperCase()), ec).map(func(s -> s.length()), ec);
	}
}

More Examples / Documentation

Converters between scala.FunctionN and java.util.function

A set of converters that enable interconversion between Java's standard Functional Interfaces defined in java.util.function and Scala's Function0, Function1, and Function2 traits. These are intended for use when you already have an instance of a java.util.function and need a Scala function, or have a Scala function and need an instance of a java.util.function.

The .asScala extension method will convert a java.util.function to the corresponding Scala function. The .asJava extension method will convert a Scala function to the most specific corresponding Java functional interface. If you wish to obtain a less specific functional interface, there are named methods that start with asJava and continue with the name of the Java functional interface. For instance, the most specific interface corresponding to the Scala function val rev = (s: String) => s.reverse is UnaryOperator[String], and that is what rev.asJava will produce. However, asJavaFunction(rev) will return a java.util.function.Function[String, String] instead.

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

Usage examples

In Scala:

import java.util.function._
import scala.compat.java8.FunctionConverters._

val foo: Int => Boolean = i => i > 7
def testBig(ip: IntPredicate) = ip.test(9)
println(testBig(foo.asJava))  // Prints true

val bar = new UnaryOperator[String]{ def apply(s: String) = s.reverse }
List("cod", "herring").map(bar.asScala)    // List("doc", "gnirrih")

def testA[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:

import java.util.function.*;
import scala.compat.java8.FunctionConverters;

class Example {
  String foo(UnaryOperator<String> f) {
    return f.apply("halibut");
  }
  String bar(scala.Function1<String, String> f) {
    return foo(functionConverters.asJavaUnaryOperator(f));
  }
  String baz(Function<String, String> f) {
    return bar(functionConverters.asScalaFromFunction(f));
  }
}

Converters between scala.concurrent and java.util.concurrent

Conversion between Java's concurrency primitives (CompletionStage and CompletableFuture) and the Scala concurrency primitives (Promise and Future) is enabled with scala.compat.java8.FutureConverters singleton object:

Converters between scala.Option and java.util classes Optional, OptionalDouble, OptionalInt, and OptionalLong.

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

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

Usage example

import scala.compat.java8.OptionConverters._

class Test {
  val o = Option(2.7)
  val oj = o.asJava        // Optional[Double]
  val ojd = o.asPrimitive  // OptionalDouble
  val ojds = ojd.asScala   // Option(2.7) again
}

Converters from Scala collections to Java 8 Streams

Scala collections gain seqStream and parStream as extension methods that produce a Java 8 Stream running sequentially or in parallel, respectively. These are automatically specialized to a primitive type if possible, including automatically applied widening conversions. For instance, List(1,2).seqStream produces an IntStream, and so does List(1.toShort, 2.toShort).parStream. Maps additionally have seqKeyStream, seqValueStream, parKeyStream, and parValueStream methods.

Scala collections also gain accumulate and stepper methods that produce utility collections that can be useful when working with Java 8 Streams. accumulate produces an Accumulator or its primitive counterpart (DoubleAccumulator, etc.), which is a low-level collection designed for efficient collection and dispatching of results to and from Streams. Unlike most collections, it can contain more than Int.MaxValue elements.

stepper produces a Stepper which is a fusion of Spliterator and Iterator. Steppers underlie the Scala collections' 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 custom collections to get better performance when streaming from these collections.

Java 8 Streams gain toScala[Coll] and accumulate methods, to make it easy to produce Scala collections or Accumulators, respectively, from Java 8 Streams. For instance, myStream.to[Vector] will collect the contents of a Stream into a scala.collection.immutable.Vector. Note that standard sequential builders are 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 of stream methods that can be used to obtain Java 8 Streams from Scala collections from within Java.

Performance Considerations

For sequential operations, Scala's iterator almost always equals or exceeds the performance of a Java 8 stream. Thus, one should favor iterator (and its richer set of operations) over seqStream for general use. However, long chains of processing of primitive types can sometimes benefit from the manually specialized methods in DoubleStream, IntStream, and LongStream.

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

For parallel operations, parStream and even seqStream.parallel meets or exceeds the performance of Scala parallel collections methods (invoked with .par). Especially for small collections, the difference can be substantial. In some cases, when a Scala (parallel) collection is the ultimate result, Scala parallel collections can have an advantage as 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 parallelization is inefficient when interfacing with Java 8 Streams (e.g. when a collection is typed as Seq[String] so might have linear access like List, but actually is a WrappedArray[String] (ArraySeq on 2.13) that can be efficiently parallelized) but can be efficient with Scala parallel collections. The parStream method is only available when the static type is known to be compatible with 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 precision to enable parStream, and an Accumulator or non-collection type is an acceptable result, Java 8 Streams will essentially always outperform the Scala parallel collections.

Scala Usage Example

import scala.compat.java8.StreamConverters._

object Test {
  val m = collection.immutable.HashMap("fish" -> 2, "bird" -> 4)
  val s = m.parValueStream.sum          // 6, potientially computed in parallel
  val t = m.seqKeyStream.toScala[List]  // List("fish", "bird")
  val a = m.accumulate                  // Accumulator[(String, Int)]

  val n = a.stepper.fold(0)(_ + _._1.length) +
          a.parStream.count             // 8 + 2 = 10

  val b = java.util.Arrays.stream(Array(2L, 3L, 4L)).
          accumulate                    // LongAccumulator
	val l = 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 than a 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 modest amount of fuss.

Example:

import scala.compat.java8.FunctionConverters._
import scala.compat.java8.StreamConverters._

def mapToSortedString[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 equal performance:

def mapToSortedString[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 usually suffices to call ScalaStreamSupport.stream(xs) on your collection xs. If xs is a map, you may wish to get the keys or values alone by using fromKeys or fromValues. If the collection has an underlying representation that is not efficiently parallelized (e.g. scala.collection.immutable.List), then fromAccumulated (and fromAccumulatedKeys and fromAccumulatedValues) will first gather the collection into an Accumulator and then return a stream over that accumulator. If not running in parallel, from is preferable (faster and less memory usage).

Note that a Scala Iterator cannot fulfill the contract of a Java 8 Stream (because it cannot support trySplit if it is called). Presently, one must call fromAccumulated on the Iterator to cache it, even if the Stream will be evaluated sequentially, or wrap it as a Java Iterator and use static methods in Spliterator to wrap that as a Spliterator and then a Stream.

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

import scala.collection.mutable.ArrayBuffer;
import scala.compat.java8.ScalaStreamSupport;

public class StreamConvertersExample {
  public int MakeAndUseArrayBuffer() {
    ArrayBuffer<String> ab = new ArrayBuffer<String>();
    ab.$plus$eq("salmon");
    ab.$plus$eq("herring");
    return ScalaStreamSupport.stream(ab).mapToInt(x -> x.length()).sum();  // 6+7 = 13
  }
}

Converters between scala.concurrent.duration.FiniteDuration and java.time.Duration

Interconversion between Java's standard java.time.Duration type and the scala.concurrent.duration.FiniteDuration types. The Java Duration does not contain a time unit, so when converting from FiniteDuration the time unit used to create it is lost.

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

Example of conversions from the Java type ways:

import scala.concurrent.duration._
import scala.compat.java8.DurationConverters._

val javaDuration: java.time.Duration = 5.seconds.toJava
val finiteDuration: FiniteDuration = javaDuration.toScala

From Java:

import scala.compat.java8.DurationConverters;
import scala.concurrent.duration.FiniteDuration;

DurationConverters.toScala(Duration.of(5, ChronoUnit.SECONDS));
DurationConverters.toJava(FiniteDuration.create(5, TimeUnit.SECONDS));

More Repositories

1

scala

Scala 2 compiler and standard library. Bugs at https://github.com/scala/bug; Scala 3 at https://github.com/scala/scala3
Scala
14,269
star
2

scala3

The Scala 3 compiler, also known as Dotty.
Scala
5,786
star
3

scala-async

An asynchronous programming facility for Scala
Scala
1,138
star
4

pickling

Fast, customizable, boilerplate-free pickling support for Scala
Scala
833
star
5

scala-parser-combinators

simple combinator-based parsing for Scala. formerly part of the Scala standard library, now a separate community-maintained module
Scala
642
star
6

docs.scala-lang

The Scala Documentation website
HTML
559
star
7

legacy-svn-scala

OBSOLETE, we're over there:
Scala
366
star
8

scala3-example-project

An example sbt project that compiles using Dotty
Scala
332
star
9

scala-xml

The standard Scala XML library
Scala
295
star
10

scala-dist

sbt project that packages the Scala distribution
Scala
276
star
11

scala-lang

sources for the Scala language website
SCSS
268
star
12

scala-abide

obsolete; visit https://github.com/scalacenter/scalafix instead
Scala
232
star
13

bug

Scala 2 bug reports only. Please, no questions โ€” proper bug reports only.
230
star
14

collection-strawman

Implementation of the new Scala 2.13 Collections
Scala
201
star
15

scala-collection-compat

makes some Scala 2.13 APIs (primarily collections, also some others) available on 2.11 and 2.12, to aid cross-building
Scala
200
star
16

scala-parallel-collections

Parallel collections standard library module for Scala 2.13+
Scala
194
star
17

scala-seed.g8

Giter8 template for a simple hello world app in Scala.
Scala
150
star
18

scala-dev

Scala 2 team issues. Not for user-facing bugs or directly actionable user-facing improvements. For build/test/infra and for longer-term planning and idea tracking. Our bug tracker is at https://github.com/scala/bug/issues
132
star
19

community-build

Scala 2 community build โ€”ย a corpus of open-source repos built against Scala nightlies
Shell
129
star
20

scala-swing

Scala wrappers for Java's Swing API for desktop GUIs
Scala
126
star
21

scala3.g8

Scala
123
star
22

scala-collection-contrib

community-contributed additions to the Scala 2.13 collections
Scala
107
star
23

scala-module-dependency-sample

Depend on Scala modules like a pro
Scala
95
star
24

scala-continuations

the Scala delimited continuations plugin and library
Scala
89
star
25

toolkit

The batteries-included Scala
Scala
87
star
26

make-release-notes

The project that generates Scala release notes.
HTML
85
star
27

vscode-scala-syntax

Visual Studio Code extension for syntax highlighting Scala sources
Scala
72
star
28

slip

obsolete โ€”ย archival use only
68
star
29

compiler-benchmark

Benchmarks for scalac
Scala
68
star
30

scala-library-next

backwards-binary-compatible Scala standard library additions
Scala
66
star
31

improvement-proposals

Scala Improvement Proposals
42
star
32

scala.epfl.ch

web site for the Scala Center @ EPFL in Switzerland
SCSS
37
star
33

scala-tool-support

XML
34
star
34

hello-world.g8

Scala
27
star
35

scala-collection-laws

partially-automatic generation of tests for the entire collections library
Scala
21
star
36

scala3-cross.g8

Scala
17
star
37

scabot

Scala's PR&CI automation bot
Scala
14
star
38

sbt-scala-module

sbt plugin for scala modules.
Scala
14
star
39

scala-jenkins-infra

A Chef cookbook that manages Scala's CI infrastructure.
Shell
14
star
40

scalatest-example.g8

Scala
13
star
41

scala3-mill-example-project

Shell
12
star
42

scala-asm

A fork of https://gitlab.ow2.org/asm/asm for the Scala compiler
12
star
43

compiler-interface

a binary contract between Zinc and Scala Compilers
Scala
10
star
44

scala-partest

Legacy repo for testing framework for Scala versions <= 2.12
Scala
9
star
45

scala-asm-legacy

A fork of asm.ow2.org for the Scala compiler
Java
8
star
46

scala3-staging.g8

Scala
7
star
47

scala-modules-build

Build support for the various Scala Modules
Shell
1
star
48

dotty.epfl.ch

The nightly documentation of scala 3
HTML
1
star
49

actors-migration

Scala
1
star
50

scala-partest-interface

SBT interface to partest
1
star
51

scala-library-all

Conglomerate pom file to pull in components of Scala standard library easily.
Scala
1
star
52

scala-dist-smoketest

Smoke Test for newly created Scala distributions
Shell
1
star
53

scala3-tasty-inspector.g8

Scala
1
star