0
# Functional Interfaces
1
2
Elasticsearch Core provides checked exception variants of standard Java functional interfaces, enabling functional programming patterns while maintaining proper exception handling. These interfaces allow throwing checked exceptions from lambda expressions and method references, which is not possible with standard Java functional interfaces.
3
4
## Capabilities
5
6
### CheckedFunction Interface
7
8
Function that can throw checked exceptions, providing the same functionality as `java.util.function.Function` but with exception handling.
9
10
```java { .api }
11
/**
12
* Represents a function that accepts one argument and produces a result,
13
* and may throw a checked exception
14
*
15
* @param <T> the type of the input to the function
16
* @param <R> the type of the result of the function
17
* @param <E> the type of the checked exception that may be thrown
18
*/
19
@FunctionalInterface
20
public interface CheckedFunction<T, R, E extends Exception> {
21
/**
22
* Applies this function to the given argument
23
* @param t the function argument
24
* @return the function result
25
* @throws E if an error occurs during function execution
26
*/
27
R apply(T t) throws E;
28
}
29
```
30
31
**Usage Examples:**
32
33
```java
34
import org.elasticsearch.core.CheckedFunction;
35
import java.io.IOException;
36
import java.nio.file.Files;
37
import java.nio.file.Path;
38
39
// Method reference with checked exception
40
CheckedFunction<Path, String, IOException> fileReader = Files::readString;
41
42
// Lambda with checked exception
43
CheckedFunction<String, Integer, NumberFormatException> parser =
44
value -> {
45
if (value == null) throw new NumberFormatException("Null value");
46
return Integer.parseInt(value);
47
};
48
49
// Usage in stream-like operations
50
public <T, R> List<R> transformWithExceptions(
51
List<T> items,
52
CheckedFunction<T, R, Exception> transformer
53
) throws Exception {
54
List<R> results = new ArrayList<>();
55
for (T item : items) {
56
results.add(transformer.apply(item));
57
}
58
return results;
59
}
60
```
61
62
### CheckedConsumer Interface
63
64
Consumer that can throw checked exceptions, with support for chaining operations.
65
66
```java { .api }
67
/**
68
* Represents an operation that accepts a single input argument and returns no
69
* result, and may throw a checked exception
70
*
71
* @param <T> the type of the input to the operation
72
* @param <E> the type of the checked exception that may be thrown
73
*/
74
@FunctionalInterface
75
public interface CheckedConsumer<T, E extends Exception> {
76
/**
77
* Performs this operation on the given argument
78
* @param t the input argument
79
* @throws E if an error occurs during operation execution
80
*/
81
void accept(T t) throws E;
82
83
/**
84
* Returns a composed CheckedConsumer that performs, in sequence, this
85
* operation followed by the after operation
86
* @param after the operation to perform after this operation
87
* @return a composed CheckedConsumer
88
*/
89
default CheckedConsumer<T, E> andThen(CheckedConsumer<? super T, E> after) {
90
Objects.requireNonNull(after);
91
return (T t) -> { accept(t); after.accept(t); };
92
}
93
}
94
```
95
96
**Usage Examples:**
97
98
```java
99
import org.elasticsearch.core.CheckedConsumer;
100
import java.io.IOException;
101
import java.io.PrintWriter;
102
import java.nio.file.Files;
103
import java.nio.file.Path;
104
105
// File writing consumer
106
CheckedConsumer<String, IOException> fileWriter = content -> {
107
Path tempFile = Files.createTempFile("temp", ".txt");
108
Files.writeString(tempFile, content);
109
};
110
111
// Chaining consumers
112
CheckedConsumer<String, IOException> logAndWrite =
113
((CheckedConsumer<String, IOException>) System.out::println)
114
.andThen(fileWriter);
115
116
// Method reference with checked exception
117
CheckedConsumer<Path, IOException> fileDeleter = Files::delete;
118
119
// Usage in batch operations
120
public void processItems(List<String> items, CheckedConsumer<String, IOException> processor)
121
throws IOException {
122
for (String item : items) {
123
processor.accept(item);
124
}
125
}
126
```
127
128
### CheckedSupplier Interface
129
130
Supplier that can throw checked exceptions, useful for lazy evaluation with exception handling.
131
132
```java { .api }
133
/**
134
* Represents a supplier of results that may throw a checked exception
135
*
136
* @param <T> the type of results supplied by this supplier
137
* @param <E> the type of the checked exception that may be thrown
138
*/
139
@FunctionalInterface
140
public interface CheckedSupplier<T, E extends Exception> {
141
/**
142
* Gets a result
143
* @return a result
144
* @throws E if an error occurs during result generation
145
*/
146
T get() throws E;
147
}
148
```
149
150
**Usage Examples:**
151
152
```java
153
import org.elasticsearch.core.CheckedSupplier;
154
import java.io.IOException;
155
import java.nio.file.Files;
156
import java.nio.file.Path;
157
import java.util.Properties;
158
159
// Lazy configuration loading
160
CheckedSupplier<Properties, IOException> configLoader = () -> {
161
Properties props = new Properties();
162
Path configFile = Path.of("config.properties");
163
if (Files.exists(configFile)) {
164
props.load(Files.newInputStream(configFile));
165
}
166
return props;
167
};
168
169
// Database connection supplier
170
CheckedSupplier<Connection, SQLException> connectionSupplier =
171
() -> DriverManager.getConnection(url, username, password);
172
173
// Memoized supplier pattern
174
public static <T, E extends Exception> CheckedSupplier<T, E> memoize(
175
CheckedSupplier<T, E> supplier
176
) {
177
return new CheckedSupplier<T, E>() {
178
private volatile T cached;
179
private volatile boolean computed;
180
181
@Override
182
public T get() throws E {
183
if (!computed) {
184
synchronized (this) {
185
if (!computed) {
186
cached = supplier.get();
187
computed = true;
188
}
189
}
190
}
191
return cached;
192
}
193
};
194
}
195
```
196
197
### CheckedRunnable Interface
198
199
Runnable that can throw checked exceptions, perfect for background tasks that need exception handling.
200
201
```java { .api }
202
/**
203
* Represents a runnable task that may throw a checked exception
204
*
205
* @param <E> the type of the checked exception that may be thrown
206
*/
207
@FunctionalInterface
208
public interface CheckedRunnable<E extends Exception> {
209
/**
210
* Executes the runnable task
211
* @throws E if an error occurs during task execution
212
*/
213
void run() throws E;
214
}
215
```
216
217
**Usage Examples:**
218
219
```java
220
import org.elasticsearch.core.CheckedRunnable;
221
import java.io.IOException;
222
import java.nio.file.Files;
223
import java.nio.file.Path;
224
import java.util.concurrent.CompletableFuture;
225
226
// File cleanup task
227
CheckedRunnable<IOException> cleanupTask = () -> {
228
Path tempDir = Path.of("temp");
229
if (Files.exists(tempDir)) {
230
Files.walk(tempDir)
231
.sorted(Comparator.reverseOrder())
232
.forEach(path -> {
233
try {
234
Files.delete(path);
235
} catch (IOException e) {
236
throw new RuntimeException(e);
237
}
238
});
239
}
240
};
241
242
// Background maintenance task
243
CheckedRunnable<Exception> maintenanceTask = () -> {
244
// Perform maintenance operations that may throw various exceptions
245
cleanupOldFiles();
246
compactDatabase();
247
refreshCaches();
248
};
249
250
// Utility for converting CheckedRunnable to standard Runnable
251
public static Runnable unchecked(CheckedRunnable<? extends Exception> checkedRunnable) {
252
return () -> {
253
try {
254
checkedRunnable.run();
255
} catch (Exception e) {
256
throw new RuntimeException(e);
257
}
258
};
259
}
260
261
// Usage with CompletableFuture
262
CompletableFuture<Void> future = CompletableFuture.runAsync(
263
unchecked(cleanupTask)
264
);
265
```
266
267
## Integration Patterns
268
269
The checked functional interfaces integrate well with exception handling patterns:
270
271
```java
272
// Exception handling utility
273
public static <T> T handleExceptions(CheckedSupplier<T, Exception> supplier) {
274
try {
275
return supplier.get();
276
} catch (RuntimeException e) {
277
throw e;
278
} catch (Exception e) {
279
throw new RuntimeException(e);
280
}
281
}
282
283
// Batch processing with exception collection
284
public static <T> List<Exception> processAll(
285
List<T> items,
286
CheckedConsumer<T, Exception> processor
287
) {
288
List<Exception> exceptions = new ArrayList<>();
289
for (T item : items) {
290
try {
291
processor.accept(item);
292
} catch (Exception e) {
293
exceptions.add(e);
294
}
295
}
296
return exceptions;
297
}
298
```