Imagine we have a list of some values and map a function that returns a list of some other type. In other words, for every value in the list, we replace it with the results of calling our function, which returns a list. We have introduced nesting and now are operating on a "list of lists of values" rather than a list of values.
However, generally you don't want to operate on a list of lists and are trying to process each value one by one -- the nesting doesn't add anything. In this case, we use flatMap, which "flattens" or concatenates the interior lists so we can operate on them like it's just a big stream of values.
This is also the case for another type like `Optional`, which represents either a value `T` or the absence of a value. An optional can be "mapped" so that a function is applied only if there is a value `T` present. flatMap works the same way here, where if you want to call another method that also produces an `Optional`, flatMap will "unwrap" the optional since you never really want to work with the type `Optional<Optional<T>>`.