Question: tags -- `["tag1", "tag2, tag3"]`

expected output -- `["tag1","tag2","tag3"]`

Current code:

```
List<String> tagsProcessed = new ArrayList<>();
for(String t : tags) {
    tagsProcessed.addAll(Stream.of(t.split(",")).map(String::trim).collect(Collectors.toList()));
}

```

How to rewrite it with streams?

Answer: 
one solution of many:

```
var delimiter = Pattern.compile(",");
tags.stream()
    .flatMap(delimiter::splitAsStream)
    .map(String::trim)
    .forEach(tagsProcessed::add);

```

---

or, *avoiding* (hiding!) the `trim` call (but without removing white spaces at start and end of input strings):

```
var delimiter = Pattern.compile("\\s*,\\s*");
tags.stream()
    .flatMap(delimiter::splitAsStream)
    .forEach(tagsProcessed::add);

```

I prefer first one, clearly showing the call to `trim`

---

all the above can also be changed to (directly) use the result of `Collectors.toList()`, but beware of kind of returned `List`. From documentation:

> 
> There are no guarantees on the type, mutability, serializability, or thread-safety of the List returned; if more control over the returned List is required, use toCollection(Supplier).
> 
> 
> 

Using it with `addAll` is not a problem (but similar to using `forEach` as in above code); also not a problem if the returned list is not being changed.
Use `flatMap`, which can map one element to any number of elements, represented as a stream. In this case, we map each tag to the array of tags produced by `split`.

```
List<String> tagsProcessed = tags.stream()
    .flatMap(tag -> Arrays.stream(tag.split(", ")))
    .collect(Collectors.toList());

```