-3

Sorry for some kind of theoretical question, but I'd like to find a way of quick reading someone else's functional code, building chain of methods use templates.

For example:

Case 1.

When I see use of .peek method or .wireTap from Spring Integration, I primarily expect logging, triggering monitoring or just transitional running external action, for instance:

.peek(params ->
    log.info("creating cache configuration {} for key class \"{}\" and value class \"{}\"",
        params.getName(), params.getKeyClass(), params.getValueClass()))

or

.peek(p ->
    Try.run(() -> cacheService.cacheProfile(p))
       .onFailure(ex ->
           log.warn("Unable to cache profile: {}", ex.toString())))

or

.wireTap(sf -> sf.handle(msg -> {
    monitoring.profileRequestsReceived();
    log.trace("Client info request(s) received: {}", msg);

Case 2.

When I see use of .map method or .transform from Spring Integration, I understand that I'm up to get result of someFunction(input), for instance:

.map(e -> GenerateTokenRs.builder().token(e.getKey()).phoneNum(e.getValue()).build())

or

.transform(Message.class, msg -> {
   ErrorResponse response = (ErrorResponse) msg.getPayload();
   MessageBuilder builder = some tranforming;
   return builder.build();
})

Current case.

But I don't have such a common view to .flatMap method. Would you give me your opinion about this, please?

Add 1:

To Turamarth: I know the difference between .map and .flatMap methods. I actively use both .map, and .flatMap in my code.

But I ask community for theirs experience and coding templates.

Torino
  • 445
  • 5
  • 12
  • Possible duplicate of [What's the difference between map and flatMap methods in Java 8?](https://stackoverflow.com/questions/26684562/whats-the-difference-between-map-and-flatmap-methods-in-java-8) – Turamarth Oct 18 '19 at 09:39
  • Typically flat map is used when we have collection of collections like list of lists, for instance `[ [a], [b,c], [d,e] ]` and we don't want to iterate over those collections like `[a]` `[b,c]` `[d,e]` but rather over its elements like `a`, `b`, `c`, `d`, `e`. So when I see `flatMap` I expect something along `streamOfElements.flatMap(ElementType::geInnerElementsAstStream)`. – Pshemo Oct 18 '19 at 10:29
  • @Turamarth it's not duplicate, have a look at my addition 1 – Torino Oct 18 '19 at 10:47

2 Answers2

3

It always helps to study the signature/javadoc of the streamish methods to understand them:

The flatMap() operation has the effect of applying a one-to-many transformation to the elements of the stream, and then flattening the resulting elements into a new stream.

So, typical code I expect, or wrote myself:

return someMap.values().stream().flatMap(Collection::stream)

The values of that map are sets, and I want to pull the entries of all these sets into a single stream for further processing here.

In other words: it is about "pulling out things", and getting them into a stream/collection for further processing.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • GhostCat, thanks for your reply! Your answer is in the way I wished to find desicions – Torino Oct 18 '19 at 10:07
  • 1
    @Torino You are very welcome. My first impulse when I saw your question title was to look for a good close reason, but I think you put in quite a lot of good thought, and I like your code examples. Now lets see if other people will contribute more examples, or if you will have to accept this answer in the end ;-) – GhostCat Oct 18 '19 at 10:46
0

I've found one more use template for .flatMap.

Let's have a look at the following code:

String s = valuesFromDb
.map(v -> v.get(k))
.getOrElse("0");

where Option<Map<String, String>> valuesFromDb = Option.of(.....).

If there's an entry k=null in the map, then we'll get null as a result of code above.

But we'd like to have "0" in this case as well.

So let's add .flatMap:

String s = valuesFromDb
.map(v -> v.get(k))
.flatMap(Option::of)
.getOrElse("0");

Regardless of having null as map's value we will get "0".

Torino
  • 445
  • 5
  • 12