CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-scala-lang-modules--scala-collection-compat

A library that makes some Scala 2.13 APIs available on Scala 2.11 and 2.12, facilitating cross-building Scala 2.13 and 3.0 code on older versions

Pending
Overview
Eval results
Files

option-converters.mddocs/

Option Converters

Utilities for converting between Scala Option and Java Optional types, enabling seamless interoperability with Java APIs.

Core Imports

import scala.jdk.OptionConverters._

OptionConverters Object

object OptionConverters {
  // Extension methods for Java Optional
  implicit class RichOptional[A](o: java.util.Optional[A]) extends AnyVal
  implicit class RichOptionalDouble(o: java.util.OptionalDouble) extends AnyVal
  implicit class RichOptionalInt(o: java.util.OptionalInt) extends AnyVal
  implicit class RichOptionalLong(o: java.util.OptionalLong) extends AnyVal
  
  // Extension methods for Scala Option
  implicit class RichOption[A](o: Option[A]) extends AnyVal
  implicit class RichOptionForJavaDouble(o: Option[Double]) extends AnyVal
  implicit class RichOptionForJavaFloat(o: Option[Float]) extends AnyVal
  implicit class RichOptionForJavaInt(o: Option[Int]) extends AnyVal
  implicit class RichOptionForJavaLong(o: Option[Long]) extends AnyVal
}

Scala Option to Java Optional

Basic Conversion

implicit class RichOption[A](o: Option[A]) extends AnyVal {
  def toJava: java.util.Optional[A]
}

Usage:

import scala.jdk.OptionConverters._

val scalaOption = Option("example")
val javaOptional: java.util.Optional[String] = scalaOption.toJava

val emptyScala = None
val emptyJava: java.util.Optional[String] = emptyScala.toJava

Primitive Specialized Conversions

Convert Scala Option to specialized Java Optional types for better performance with primitives.

implicit class RichOptionForJavaDouble(o: Option[Double]) extends AnyVal {
  def toJavaPrimitive: java.util.OptionalDouble
}

implicit class RichOptionForJavaFloat(o: Option[Float]) extends AnyVal {
  def toJavaPrimitive: java.util.OptionalDouble  // Converts to Double
}

implicit class RichOptionForJavaInt(o: Option[Int]) extends AnyVal {
  def toJavaPrimitive: java.util.OptionalInt
}

implicit class RichOptionForJavaLong(o: Option[Long]) extends AnyVal {
  def toJavaPrimitive: java.util.OptionalLong
}

Usage:

import scala.jdk.OptionConverters._

val intOption = Option(42)
val javaOptionalInt: java.util.OptionalInt = intOption.toJavaPrimitive

val doubleOption = Option(3.14)
val javaOptionalDouble: java.util.OptionalDouble = doubleOption.toJavaPrimitive

val longOption = Option(123456789L)
val javaOptionalLong: java.util.OptionalLong = longOption.toJavaPrimitive

Java Optional to Scala Option

Basic Conversion

implicit class RichOptional[A](o: java.util.Optional[A]) extends AnyVal {
  def toScala: Option[A]
}

Usage:

import scala.jdk.OptionConverters._
import java.util.Optional

val javaOptional = Optional.of("example")
val scalaOption: Option[String] = javaOptional.toScala

val emptyJava = Optional.empty[String]()
val emptyScala: Option[String] = emptyJava.toScala

Primitive Optional Conversions

implicit class RichOptionalDouble(o: java.util.OptionalDouble) extends AnyVal {
  def toScala: Option[Double]
  def toJavaGeneric: java.util.Optional[Double]
}

implicit class RichOptionalInt(o: java.util.OptionalInt) extends AnyVal {
  def toScala: Option[Int]
  def toJavaGeneric: java.util.Optional[Int]
}

implicit class RichOptionalLong(o: java.util.OptionalLong) extends AnyVal {
  def toScala: Option[Long]
  def toJavaGeneric: java.util.Optional[Long]
}

Usage:

import scala.jdk.OptionConverters._
import java.util.{OptionalInt, OptionalDouble, OptionalLong}

val javaInt = OptionalInt.of(42)
val scalaInt: Option[Int] = javaInt.toScala
val genericJavaInt: java.util.Optional[Int] = javaInt.toJavaGeneric

val javaDouble = OptionalDouble.of(3.14)
val scalaDouble: Option[Double] = javaDouble.toScala

val javaLong = OptionalLong.of(123456789L)
val scalaLong: Option[Long] = javaLong.toScala

Generic Optional Conversions

Convert between generic and specialized Optional types.

implicit class RichOptional[A](o: java.util.Optional[A]) extends AnyVal {
  def toJavaPrimitive: OptionalInt     // When A =:= Int
  def toJavaPrimitive: OptionalLong    // When A =:= Long  
  def toJavaPrimitive: OptionalDouble  // When A =:= Double
}

Usage:

import scala.jdk.OptionConverters._
import java.util.Optional

val genericInt: Optional[Int] = Optional.of(42)
val primitiveInt: java.util.OptionalInt = genericInt.toJavaPrimitive

val genericDouble: Optional[Double] = Optional.of(3.14)
val primitiveDouble: java.util.OptionalDouble = genericDouble.toJavaPrimitive

Complete Usage Example

import scala.jdk.OptionConverters._
import java.util.{Optional, OptionalInt}

// Working with Java APIs that return Optional
def getJavaOptionalValue(): Optional[String] = Optional.of("Hello")
def getJavaPrimitiveValue(): OptionalInt = OptionalInt.of(42)

// Convert Java Optional to Scala Option for processing
val scalaString: Option[String] = getJavaOptionalValue().toScala
val processedString = scalaString.map(_.toUpperCase)

val scalaInt: Option[Int] = getJavaPrimitiveValue().toScala  
val processedInt = scalaInt.map(_ * 2)

// Convert back to Java Optional when calling Java APIs
def callJavaAPI(value: Optional[String]): Unit = println(s"Java received: $value")
def callJavaIntAPI(value: OptionalInt): Unit = println(s"Java received: $value")

callJavaAPI(processedString.toJava)
callJavaIntAPI(processedInt.toJavaPrimitive)

Java Interoperability Patterns

Repository Pattern with Optional

import scala.jdk.OptionConverters._
import java.util.Optional

trait UserRepository {
  def findById(id: Long): Optional[User]  // Java interface
}

class ScalaUserService(repo: UserRepository) {
  def getUser(id: Long): Option[User] = {
    repo.findById(id).toScala  // Convert to Scala Option
  }
  
  def getUserName(id: Long): Option[String] = {
    getUser(id).map(_.name)
  }
}

Null-Safe Configuration

import scala.jdk.OptionConverters._
import java.util.Optional

def getConfigValue(key: String): Optional[String] = {
  Option(System.getProperty(key)).toJava
}

def getIntConfigValue(key: String): OptionalInt = {
  Option(System.getProperty(key))
    .flatMap(_.toIntOption)
    .toJavaPrimitive
}

Performance Notes

  • Primitive specialized Optional types (OptionalInt, OptionalLong, OptionalDouble) avoid boxing overhead
  • Use toJavaPrimitive when working with numeric types for better performance
  • Conversions have minimal overhead as they create wrapper objects rather than copying data

Install with Tessl CLI

npx tessl i tessl/maven-org-scala-lang-modules--scala-collection-compat

docs

annotation-backports.md

backported-collections.md

collection-extensions.md

collection-factories.md

index.md

iterator-size-ops.md

java-interop.md

map-extensions.md

method-chaining.md

option-converters.md

resource-management.md

string-parsing.md

tile.json