W3cubDocs

/Scala 2.13 Library

Package scala.jdk

package jdk

Package Members

package javaapi

Type Members

abstract class Accumulator[A, +CC[X] <: collection.mutable.Seq[X], +C <: collection.mutable.Seq[A]] extends collection.mutable.Seq[A] with Builder[A, C]

Accumulators are mutable sequences with two distinct features:

    An accumulator can be appended efficiently to anotherThere are manually specialized Accumulators for Int, Long and Double that don't box the elements

These two features make Accumulators a good candidate to collect the results of a parallel Java stream pipeline into a Scala collection. The scala.collection.convert.StreamExtensions.StreamHasToScala.toScala extension method on Java streams (available by importing scala.jdk.StreamConverters._) is specialized for Accumulators: they are built in parallel, the parts are merged efficiently.

Building specialized Accumulators is handled transparently. As a user, using the Accumulator object as a factory automatically creates an IntAccumulator, LongAccumulator, DoubleAccumulator or AnyAccumulator depending on the element type.

Note: to run the example, start the Scala REPL with scala -Yrepl-class-based to avoid deadlocks, see https://github.com/scala/bug/issues/9076.

scala> import scala.jdk.StreamConverters._
import scala.jdk.StreamConverters._

scala> def isPrime(n: Int): Boolean = !(2 +: (3 to Math.sqrt(n).toInt by 2) exists (n % _ == 0))
isPrime: (n: Int)Boolean

scala> val intAcc = (1 to 10000).asJavaParStream.filter(isPrime).toScala(scala.jdk.Accumulator)
intAcc: scala.jdk.IntAccumulator = IntAccumulator(1, 3, 5, 7, 11, 13, 17, 19, ...

scala> val stringAcc = (1 to 100).asJavaParStream.mapToObj("<>" * _).toScala(Accumulator)
stringAcc: scala.jdk.AnyAccumulator[String] = AnyAccumulator(<>, <><>, <><><>, ...

There are two possibilities to process elements of a primitive Accumulator without boxing: specialized operations of the Accumulator, or the Stepper interface. The most common collection operations are overloaded or overridden in the primitive Accumulator classes, for example IntAccumulator.map or IntAccumulator.exists. Thanks to Scala's function specialization, intAcc.exists(x => testOn(x)) does not incur boxing.

The Stepper interface provides iterator-like hasStep and nextStep methods, and is specialized for Int, Long and Double. The intAccumulator.stepper method creates an scala.collection.IntStepper that yields the elements of the accumulator without boxing.

Accumulators can hold more than Int.MaxValue elements. They have a sizeLong method that returns the size as a Long. Note that certain operations defined in scala.collection.Seq are implemented using length, so they will not work correctly for large accumulators.

The Accumulator class is a base class to share code between AnyAccumulator (for reference types) and the manual specializations IntAccumulator, LongAccumulator and DoubleAccumulator.

final class AnyAccumulator[A] extends Accumulator[A, AnyAccumulator, AnyAccumulator[A]] with SeqOps[A, AnyAccumulator, AnyAccumulator[A]] with IterableFactoryDefaults[A, AnyAccumulator] with Serializable

final class DoubleAccumulator extends Accumulator[Double, AnyAccumulator, DoubleAccumulator] with SeqOps[Double, AnyAccumulator, DoubleAccumulator] with Serializable

final class IntAccumulator extends Accumulator[Int, AnyAccumulator, IntAccumulator] with SeqOps[Int, AnyAccumulator, IntAccumulator] with Serializable

final class LongAccumulator extends Accumulator[Long, AnyAccumulator, LongAccumulator] with SeqOps[Long, AnyAccumulator, LongAccumulator] with Serializable

sealed abstract class OptionShape[A, O] extends AnyRef

A type class implementing conversions from a generic Scala Option or Java Optional to a specialized Java variant (for Double, Int and Long).

A

the primitive type wrapped in an option

O

the specialized Java Optional wrapping an element of type A

Annotations
@implicitNotFound("No specialized Optional type exists for elements of type ${A}")

trait Priority0FunctionExtensions extends Priority1FunctionExtensions

trait Priority1FunctionExtensions extends Priority2FunctionExtensions

trait Priority2FunctionExtensions extends Priority3FunctionExtensions

trait Priority3FunctionExtensions extends AnyRef

Value Members

object Accumulator

Contains factory methods to build Accumulators.

Note that the Accumulator object itself is not a factory, but it is implicitly convert to a factory according to the element type, see Accumulator.toFactory.

This allows passing the Accumulator object as argument when a collection.Factory, and the implicit Accumulator.AccumulatorFactoryShape instance is used to build a specialized Accumulator according to the element type:

scala> val intAcc = Accumulator(1,2,3)
intAcc: scala.collection.convert.IntAccumulator = IntAccumulator(1, 2, 3)

scala> val anyAccc = Accumulator("K")
anyAccc: scala.collection.convert.AnyAccumulator[String] = AnyAccumulator(K)

scala> val intAcc2 = List(1,2,3).to(Accumulator)
intAcc2: scala.jdk.IntAccumulator = IntAccumulator(1, 2, 3)

scala> val anyAcc2 = List("K").to(Accumulator)
anyAcc2: scala.jdk.AnyAccumulator[String] = AnyAccumulator(K)

object AnyAccumulator extends SeqFactory[AnyAccumulator]

object CollectionConverters extends AsJavaExtensions with AsScalaExtensions

This object provides extension methods that convert between Scala and Java collections.

When writing Java code, use the explicit conversion methods defined in javaapi.CollectionConverters instead.

Note: to create Java Streams that operate on Scala collections (sequentially or in parallel), use StreamConverters.

import scala.jdk.CollectionConverters._
val s: java.util.Set[String] = Set("one", "two").asJava

The conversions return adapters for the corresponding API, i.e., the collections are wrapped, not converted. Changes to the original collection are reflected in the view, and vice versa:

scala> import scala.jdk.CollectionConverters._

scala> val s = collection.mutable.Set("one")
s: scala.collection.mutable.Set[String] = HashSet(one)

scala> val js = s.asJava
js: java.util.Set[String] = [one]

scala> js.add("two")

scala> s
res2: scala.collection.mutable.Set[String] = HashSet(two, one)

The following conversions are supported via asScala and asJava:

scala.collection.Iterable       <=> java.lang.Iterable
scala.collection.Iterator       <=> java.util.Iterator
scala.collection.mutable.Buffer <=> java.util.List
scala.collection.mutable.Set    <=> java.util.Set
scala.collection.mutable.Map    <=> java.util.Map
scala.collection.concurrent.Map <=> java.util.concurrent.ConcurrentMap

The following conversions are supported via asScala and through specially-named extension methods to convert to Java collections, as shown:

scala.collection.Iterable    <=> java.util.Collection   (via asJavaCollection)
scala.collection.Iterator    <=> java.util.Enumeration  (via asJavaEnumeration)
scala.collection.mutable.Map <=> java.util.Dictionary   (via asJavaDictionary)

In addition, the following one-way conversions are provided via asJava:

scala.collection.Seq         => java.util.List
scala.collection.mutable.Seq => java.util.List
scala.collection.Set         => java.util.Set
scala.collection.Map         => java.util.Map

The following one way conversion is provided via asScala:

java.util.Properties => scala.collection.mutable.Map

In all cases, converting from a source type to a target type and back again will return the original source object. For example:

import scala.jdk.CollectionConverters._

val source = new scala.collection.mutable.ListBuffer[Int]
val target: java.util.List[Int] = source.asJava
val other: scala.collection.mutable.Buffer[Int] = target.asScala
assert(source eq other)

object DoubleAccumulator extends SpecificIterableFactory[Double, DoubleAccumulator] with java.io.Serializable

object DurationConverters

This object provides extension methods that convert between Scala and Java duration types.

When writing Java code, use the explicit conversion methods defined in javaapi.DurationConverters instead.

object FunctionConverters extends Priority0FunctionExtensions

This object provides extension methods that convert between Scala and Java function types.

When writing Java code, use the explicit conversion methods defined in javaapi.FunctionConverters instead.

Using the .asJava extension method on a Scala function produces the most specific possible Java function type:

scala> import scala.jdk.FunctionConverters._
scala> val f = (x: Int) => x + 1

scala> val jf1 = f.asJava
jf1: java.util.function.IntUnaryOperator = ...

More generic Java function types can be created using the corresponding asJavaXYZ extension method:

scala> val jf2 = f.asJavaFunction
jf2: java.util.function.Function[Int,Int] = ...

scala> val jf3 = f.asJavaUnaryOperator
jf3: java.util.function.UnaryOperator[Int] = ...

Converting a Java function to Scala is done using the asScala extension method:

scala> List(1,2,3).map(jf2.asScala)
res1: List[Int] = List(2, 3, 4)

object FunctionWrappers

object FutureConverters

This object provides extension methods that convert between Scala Future and Java CompletionStage

When writing Java code, use the explicit conversion methods defined in javaapi.FutureConverters instead.

Note that the bridge is implemented at the read-only side of asynchronous handles, namely Future (instead of scala.concurrent.Promise) and CompletionStage (instead of java.util.concurrent.CompletableFuture). This is intentional, as the semantics of bridging the write-handles would be prone to race conditions; if both ends (CompletableFuture and Promise) are completed independently at the same time, they may contain different values afterwards. For this reason, toCompletableFuture is not supported on the created CompletionStages.

object IntAccumulator extends SpecificIterableFactory[Int, IntAccumulator] with java.io.Serializable

object LongAccumulator extends SpecificIterableFactory[Long, LongAccumulator] with java.io.Serializable

object OptionConverters

This object provides extension methods that convert between Scala Option and Java Optional types.

When writing Java code, use the explicit conversion methods defined in javaapi.OptionConverters instead.

Scala Option is extended with a toJava method that creates a corresponding Optional, and a toJavaPrimitive method that creates a specialized variant (e.g., OptionalInt) if applicable.

Java Optional is extended with a toScala method and a toJavaPrimitive method.

Finally, specialized Optional types are extended with toScala and toJavaGeneric methods.

Example usage:

import scala.jdk.OptionConverters._
val a = Option("example").toJava      // Creates java.util.Optional[String] containing "example"
val b = (None: Option[String]).toJava // Creates an empty java.util.Optional[String]
val c = a.toScala                     // Back to Option("example")
val d = b.toScala                     // Back to None typed as Option[String]
val e = Option(2.7).toJava            // java.util.Optional[Double] containing boxed 2.7
val f = Option(2.7).toJavaPrimitive   // java.util.OptionalDouble containing 2.7 (not boxed)
val g = f.toScala                     // Back to Option(2.7)
val h = f.toJavaGeneric               // Same as e
val i = e.toJavaPrimitive             // Same as f

object OptionShape

object StreamConverters extends StreamExtensions

This object provides extension methods to create Java Streams that operate on Scala collections (sequentially or in parallel). For more information on Java streams, consult the documentation (https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html).

When writing Java code, use the explicit conversion methods defined in javaapi.StreamConverters instead.

The methods asJavaSeqStream and asJavaParStream convert a collection to a Java Stream:

scala> import scala.jdk.StreamConverters._

scala> val s = (1 to 10).toList.asJavaSeqStream
s: java.util.stream.IntStream = [email protected]

scala> s.map(_ * 2).filter(_ > 5).toScala(List)
res1: List[Int] = List(6, 8, 10, 12, 14, 16, 18, 20)

Note: using parallel streams in the Scala REPL causes deadlocks, see https://github.com/scala/bug/issues/9076. As a workaround, use scala -Yrepl-class-based.

scala> def isPrime(n: Int): Boolean = !(2 +: (3 to Math.sqrt(n).toInt by 2) exists (n % _ == 0))
isPrime: (n: Int)Boolean

scala> (10000 to 1000000).asJavaParStream.filter(isPrime).toScala(Vector)
res6: scala.collection.immutable.Vector[Int] = Vector(10007, 10009, 10037, 10039, ...

A Java Stream provides operations on a sequence of elements. Streams are created from Spliterators, which are similar to Iterators with the additional capability to partition off some of their elements. This partitioning, if supported by the Spliterator, is used for parallelizing Stream operations.

Scala collections have a method stepper that returns a scala.collection.Stepper for the collection, which in turn can be converted to a Spliterator for creating a Java Stream.

The asJavaSeqStream extension method is available on any Scala collection. The asJavaParStream extension method can only be invoked on collections where the return type of the stepper method is marked with the scala.collection.Stepper.EfficientSplit marker trait. This trait is added to steppers that support partitioning, and therefore efficient parallel processing.

The following extension methods are available:

Collection Type

Extension Methods

IterableOnce

asJavaSeqStream

IndexedSeq, Arrays, BitSet, Accumulator, HashMap, HashSet, Range, TreeMap, TreeSet, Vector, Strings

asJavaParStream

Map

asJavaSeqKeyStream, asJavaSeqValueStream

HashMap, TreeMap

asJavaParKeyStream, asJavaParValueStream

Stepper

asJavaSeqStream

Stepper with EfficientSplit

asJavaParStream

Strings

asJavaSeqStream, asJavaParStream, asJavaSeqCharStream, asJavaParCharStream, asJavaSeqCodePointStream, asJavaParCodePointStream

Java streams

toScala, asJavaPrimitiveStream

The asJavaPrimitiveStream method converts a Stream[Int] to an IntStream. It is the dual of the boxed method defined on primitive streams (e.g., IntStream.boxed is a Stream[Integer]).

The toScala extension methods on Java streams collects the result of a stream pipeline into a Scala collection, for example stream.toScala(List), stream.toScala(Vector). Note that transformation operations on streams are lazy (also called "intermediate"), terminal operations such as forEach, count or toScala trigger the evaluation.

Collecting a parallel stream to a collection can be performed in parallel. This is beneficial if the target collection supports efficient merging of the segments that are built in parallel. To support this use case, the Scala standard library provides the Accumulator collection. This collection supports efficient parallel construction, and it has specialized subtypes for Int, Long and Double so that primitive Java streams can be collected to a Scala collection without boxing the elements.

© 2002-2019 EPFL, with contributions from Lightbend.
Licensed under the Apache License, Version 2.0.
https://www.scala-lang.org/api/2.13.0/scala/jdk/index.html