Using flatmap
Let’s imagine you have a list of IDs, and your findById
method returns an Optional<Message>
.
List<UUID> ids = List.of(id1, id2, id3);
Stream<Optional<Message>> streamOfOptionals = ids.stream()
.map(this::findById); // Let's say id2 doesn't exist
At this point, streamOfOptionals
looks conceptually like this: [ Optional[MessageA], Optional.empty, Optional[MessageC] ]
Now, we apply .flatMap(Optional::stream)
. The flatMap
operation goes through each element and applies the Optional::stream
function:
- First element:
Optional[MessageA]
Optional[MessageA].stream()
is called.- It returns a new stream:
Stream[MessageA]
- Second element:
Optional.empty
Optional.empty.stream()
is called.- It returns a new, empty stream:
Stream[]
- Third element:
Optional[MessageC]
Optional[MessageC].stream()
is called.- It returns a new stream:
Stream[MessageC]
Finally, flatMap
takes all these resulting streams and “flattens” them into one single stream: Stream[MessageA]
+ Stream[]
+ Stream[MessageC]
The final result is a clean Stream<Message>
: [ MessageA, MessageC ]
The empty Optional
was elegantly and safely discarded without any if
checks or isPresent()
calls
Lambda to method reference
// lambda
.map(path -> getReadStatus(path))
// metohod reference
.map(FileReadStatusRepository::getReadStatus)
What it means: “For every element that comes through the stream, I want you to call the getReadStatus
method (which belongs to the FileReadStatusRepository
class) and use the stream element as the input argument.”
순서
// FROM (dangerous)
.anyMatch(c -> c.getName().equals(channelName));
// TO (safe)
.anyMatch(c -> channelName.equals(c.getName()));
- You should never assume that data you read from an external source (like a file) is perfect. You need to write your code to be “null-safe.”
- safe - defensive coding
- Here, if c.getName() is null, channelName.equals(null) will correctly return false instead of crashing.
The problem
The problem isn’t in the existsByName
method itself, but in the data it’s processing.
- Your method
Files.list(directory)
gets all the files in your channel directory. - The
.map(FileChannelRepository::getChannel)
step reads each.ser
file and deserializes it into aChannel
object. - Crucially, at least ONE of your
.ser
files on the disk represents aChannel
object where thename
field isnull
.
This “bad” Channel
object then enters the anyMatch
step, and when the lambda c -> c.getName().equals(channelName)
is executed for that specific object, it blows up. The ChannelResponseDto
you posted is for a valid channel; the error is being caused by an invalid one that’s also in the same directory.