0

I have an object called UserSettings which contains a list of another object called SettingsFolder. This object in-turn has a List of SettingsFolders. The idea is to mimic a user that has a set of folders and folders can have subfolders. I am trying to write a lambda function which will find a given object provided the given ID.

Right now I have 2 lambdas, one which converts the top-level folder into streams and checks if the Id exists and returns the object and another which checks the sub-folder.

For parent Level folder

SettingsFolder settingsFolder = userSettings.getFolders().stream()
    .filter(folder -> folder.getId().equals(UUID.fromString(form.getFolderId())))
    .findAny()
    .orElse(null);

For SubFolder

List<SettingsFolder> settingsFolders = userSettings.getFolders().stream()
    .filter(folder -> folder.getFolders() != null)
    .filter(folder -> folder.getFolders().size() > 0)
    .collect(Collectors.toList());
SettingsFolder subFolder = settingsFolders.stream()
    .flatMap(e -> e.getFolders().stream())
    .filter(c -> c.getId() != null)
    .filter(c -> c.getId().equals(UUID.fromString(form.getFolderId())))
    .findAny()
    .orElse(null);

Is there a way to combine 2 lambdas into one which will ideally check all these lists recursively?

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
SteeleDev
  • 169
  • 1
  • 3
  • 12
  • 4
    *Note:* `c -> c.getId() != null` is called a **lambda** expression. The method chain starting with `stream()` and ending with `collect()` or `findAny()` is called a Java **stream**. You can write streams that don't use any lambda expressions, e.g. by using *method references* instead. You can use lambda expressions without using stream, i.e. anywhere a functional interface needs an implementation. Streams and lambdas are very commonly used together, so can be confused, but please use the correct terminology. – Andreas Jun 04 '19 at 15:56
  • 1
    The recursion has to be done by your class, e.g. see [Recursive use of Stream.flatMap()](https://stackoverflow.com/q/32656888/5221149) – Andreas Jun 04 '19 at 16:04
  • 1
    Possible duplicate of all kind of things, like [stream](https://stackoverflow.com/questions/26158082/how-to-convert-a-tree-structure-to-a-stream-of-nodes-in-java) and flatMap-related (as @Andreas suggests), and countless topics about recursive lambdas, https://stackoverflow.com/questions/24509441/why-do-lambdas-in-java-8-disallow-forward-reference-to-member-variables-where-an, https://stackoverflow.com/questions/25252953/recursive-lambda-expressions-in-java-8/25253278#25253278, https://stackoverflow.com/questions/19429667/implement-recursive-lambda-function-using-java-8 – tevemadar Jun 04 '19 at 16:07
  • 2
    Note that `.filter(folder -> folder.getFolders().size() > 0)` is obsolete, the subsequent processing does handle empty lists the right way anyway. Further, the two filter steps `.filter(c -> c.getId() != null) .filter(c -> c.getId().equals(UUID.fromString(form.getFolderId())))` can be combined to a single `.filter(c -> UUID.fromString(form.getFolderId()).equals(c.getId()))`. Also, the two stream statements can be combined to a single one easily, just remove the `.collect(Collectors.toList())` step and chain the operations of the second stream. However, that’s not recursive. – Holger Jun 04 '19 at 16:44

0 Answers0