0
# Option Converters
1
2
Utilities for converting between Scala `Option` and Java `Optional` types, enabling seamless interoperability with Java APIs.
3
4
## Core Imports
5
6
```scala
7
import scala.jdk.OptionConverters._
8
```
9
10
## OptionConverters Object
11
12
```scala { .api }
13
object OptionConverters {
14
// Extension methods for Java Optional
15
implicit class RichOptional[A](o: java.util.Optional[A]) extends AnyVal
16
implicit class RichOptionalDouble(o: java.util.OptionalDouble) extends AnyVal
17
implicit class RichOptionalInt(o: java.util.OptionalInt) extends AnyVal
18
implicit class RichOptionalLong(o: java.util.OptionalLong) extends AnyVal
19
20
// Extension methods for Scala Option
21
implicit class RichOption[A](o: Option[A]) extends AnyVal
22
implicit class RichOptionForJavaDouble(o: Option[Double]) extends AnyVal
23
implicit class RichOptionForJavaFloat(o: Option[Float]) extends AnyVal
24
implicit class RichOptionForJavaInt(o: Option[Int]) extends AnyVal
25
implicit class RichOptionForJavaLong(o: Option[Long]) extends AnyVal
26
}
27
```
28
29
## Scala Option to Java Optional
30
31
### Basic Conversion
32
33
```scala { .api }
34
implicit class RichOption[A](o: Option[A]) extends AnyVal {
35
def toJava: java.util.Optional[A]
36
}
37
```
38
39
**Usage:**
40
```scala
41
import scala.jdk.OptionConverters._
42
43
val scalaOption = Option("example")
44
val javaOptional: java.util.Optional[String] = scalaOption.toJava
45
46
val emptyScala = None
47
val emptyJava: java.util.Optional[String] = emptyScala.toJava
48
```
49
50
### Primitive Specialized Conversions
51
52
Convert Scala `Option` to specialized Java `Optional` types for better performance with primitives.
53
54
```scala { .api }
55
implicit class RichOptionForJavaDouble(o: Option[Double]) extends AnyVal {
56
def toJavaPrimitive: java.util.OptionalDouble
57
}
58
59
implicit class RichOptionForJavaFloat(o: Option[Float]) extends AnyVal {
60
def toJavaPrimitive: java.util.OptionalDouble // Converts to Double
61
}
62
63
implicit class RichOptionForJavaInt(o: Option[Int]) extends AnyVal {
64
def toJavaPrimitive: java.util.OptionalInt
65
}
66
67
implicit class RichOptionForJavaLong(o: Option[Long]) extends AnyVal {
68
def toJavaPrimitive: java.util.OptionalLong
69
}
70
```
71
72
**Usage:**
73
```scala
74
import scala.jdk.OptionConverters._
75
76
val intOption = Option(42)
77
val javaOptionalInt: java.util.OptionalInt = intOption.toJavaPrimitive
78
79
val doubleOption = Option(3.14)
80
val javaOptionalDouble: java.util.OptionalDouble = doubleOption.toJavaPrimitive
81
82
val longOption = Option(123456789L)
83
val javaOptionalLong: java.util.OptionalLong = longOption.toJavaPrimitive
84
```
85
86
## Java Optional to Scala Option
87
88
### Basic Conversion
89
90
```scala { .api }
91
implicit class RichOptional[A](o: java.util.Optional[A]) extends AnyVal {
92
def toScala: Option[A]
93
}
94
```
95
96
**Usage:**
97
```scala
98
import scala.jdk.OptionConverters._
99
import java.util.Optional
100
101
val javaOptional = Optional.of("example")
102
val scalaOption: Option[String] = javaOptional.toScala
103
104
val emptyJava = Optional.empty[String]()
105
val emptyScala: Option[String] = emptyJava.toScala
106
```
107
108
### Primitive Optional Conversions
109
110
```scala { .api }
111
implicit class RichOptionalDouble(o: java.util.OptionalDouble) extends AnyVal {
112
def toScala: Option[Double]
113
def toJavaGeneric: java.util.Optional[Double]
114
}
115
116
implicit class RichOptionalInt(o: java.util.OptionalInt) extends AnyVal {
117
def toScala: Option[Int]
118
def toJavaGeneric: java.util.Optional[Int]
119
}
120
121
implicit class RichOptionalLong(o: java.util.OptionalLong) extends AnyVal {
122
def toScala: Option[Long]
123
def toJavaGeneric: java.util.Optional[Long]
124
}
125
```
126
127
**Usage:**
128
```scala
129
import scala.jdk.OptionConverters._
130
import java.util.{OptionalInt, OptionalDouble, OptionalLong}
131
132
val javaInt = OptionalInt.of(42)
133
val scalaInt: Option[Int] = javaInt.toScala
134
val genericJavaInt: java.util.Optional[Int] = javaInt.toJavaGeneric
135
136
val javaDouble = OptionalDouble.of(3.14)
137
val scalaDouble: Option[Double] = javaDouble.toScala
138
139
val javaLong = OptionalLong.of(123456789L)
140
val scalaLong: Option[Long] = javaLong.toScala
141
```
142
143
## Generic Optional Conversions
144
145
Convert between generic and specialized `Optional` types.
146
147
```scala { .api }
148
implicit class RichOptional[A](o: java.util.Optional[A]) extends AnyVal {
149
def toJavaPrimitive: OptionalInt // When A =:= Int
150
def toJavaPrimitive: OptionalLong // When A =:= Long
151
def toJavaPrimitive: OptionalDouble // When A =:= Double
152
}
153
```
154
155
**Usage:**
156
```scala
157
import scala.jdk.OptionConverters._
158
import java.util.Optional
159
160
val genericInt: Optional[Int] = Optional.of(42)
161
val primitiveInt: java.util.OptionalInt = genericInt.toJavaPrimitive
162
163
val genericDouble: Optional[Double] = Optional.of(3.14)
164
val primitiveDouble: java.util.OptionalDouble = genericDouble.toJavaPrimitive
165
```
166
167
## Complete Usage Example
168
169
```scala
170
import scala.jdk.OptionConverters._
171
import java.util.{Optional, OptionalInt}
172
173
// Working with Java APIs that return Optional
174
def getJavaOptionalValue(): Optional[String] = Optional.of("Hello")
175
def getJavaPrimitiveValue(): OptionalInt = OptionalInt.of(42)
176
177
// Convert Java Optional to Scala Option for processing
178
val scalaString: Option[String] = getJavaOptionalValue().toScala
179
val processedString = scalaString.map(_.toUpperCase)
180
181
val scalaInt: Option[Int] = getJavaPrimitiveValue().toScala
182
val processedInt = scalaInt.map(_ * 2)
183
184
// Convert back to Java Optional when calling Java APIs
185
def callJavaAPI(value: Optional[String]): Unit = println(s"Java received: $value")
186
def callJavaIntAPI(value: OptionalInt): Unit = println(s"Java received: $value")
187
188
callJavaAPI(processedString.toJava)
189
callJavaIntAPI(processedInt.toJavaPrimitive)
190
```
191
192
## Java Interoperability Patterns
193
194
### Repository Pattern with Optional
195
196
```scala
197
import scala.jdk.OptionConverters._
198
import java.util.Optional
199
200
trait UserRepository {
201
def findById(id: Long): Optional[User] // Java interface
202
}
203
204
class ScalaUserService(repo: UserRepository) {
205
def getUser(id: Long): Option[User] = {
206
repo.findById(id).toScala // Convert to Scala Option
207
}
208
209
def getUserName(id: Long): Option[String] = {
210
getUser(id).map(_.name)
211
}
212
}
213
```
214
215
### Null-Safe Configuration
216
217
```scala
218
import scala.jdk.OptionConverters._
219
import java.util.Optional
220
221
def getConfigValue(key: String): Optional[String] = {
222
Option(System.getProperty(key)).toJava
223
}
224
225
def getIntConfigValue(key: String): OptionalInt = {
226
Option(System.getProperty(key))
227
.flatMap(_.toIntOption)
228
.toJavaPrimitive
229
}
230
```
231
232
## Performance Notes
233
234
- Primitive specialized `Optional` types (`OptionalInt`, `OptionalLong`, `OptionalDouble`) avoid boxing overhead
235
- Use `toJavaPrimitive` when working with numeric types for better performance
236
- Conversions have minimal overhead as they create wrapper objects rather than copying data