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:

  1. First element: Optional[MessageA]
    • Optional[MessageA].stream() is called.
    • It returns a new stream: Stream[MessageA]
  2. Second element: Optional.empty
    • Optional.empty.stream() is called.
    • It returns a new, empty stream: Stream[]
  3. 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.

  1. Your method Files.list(directory) gets all the files in your channel directory.
  2. The .map(FileChannelRepository::getChannel) step reads each .ser file and deserializes it into a Channel object.
  3. Crucially, at least ONE of your .ser files on the disk represents a Channel object where the name field is null.

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.