I'm creating a custom Collector but it is failing when using it while compiling.
private static <T> Collector<T, ?, T> getFirstElement() {
return Collectors.collectingAndThen(
Collectors.toList(),
list -> {
if (list.size() == 0) {
return null;
}
if (list.size() > 1) {
log.info("There are more than 1 registry");
}
return list.get(0);
}
);
}
String myString = "test";
Optional.of(myString)
.map(myService::getFromDatabase)
.collect(getFirstElement());
myService.getFromDatabase(string) return a list of Items.
I receive an error while compiling
cannot find symbol
[ERROR] symbol: method collect(java.util.stream.Collector<java.lang.Object,capture#1 of ?,java.lang.Object>)
[ERROR] location: class java.util.Optional<java.util.List<com.package.Item>>
Why am I having this error?
As I've said, there are no issues with your collector.
Method collect()
isn't accessible on the object of type Optional
. It has methods map()
, filter()
, stream()
, but you can't apply collect()
on it, don't confuse optional with a stream.
If you need to verify that the string value that has to be passed as an argument into getFromDatabase()
isn't null
you can use Objects.requireNonNull()
(note that Optional.of()
will throw an exception in the case if the argument is null
).
Assuming that getFromDatabase()
returns a list Item
objects, you can write your code like this:
List<Item> items =
Stream.of(Objects.requireNonNull(myString, "error message")) // Stream<String>
.map(myService::getFromDatabase) // Stream<List<Item>>
.flatMap(List::stream) // Stream<Item>
.collect(getFirstElement());
If your intention while you were using Optional.of()
was to create a result of type Optinal<List<Item>>
that's not a good idea (apart from the fact that it would not compile).
Optional, containing a collection is an antipattern because it introduces an unnecessary redundancy. Empty collection serves the same purpose, indicating that there's no data, so there's no need to utilize optional for that.