4

I have a String field called userId that has comma separated values like String user = "123","456" I want to split it. I have written something like this

List<String> idList= employeeList.stream()
    .map(UserDto::getUserId)
    .filter(Objects::nonNull)
    .map(String::toUpperCase)
    .distinct()
    .collect(Collectors.toList());

This UserDto::getUserId contains the comma separated values. Is it possible to split when streaming in the above logic.

Thanks

ernest_k
  • 44,416
  • 5
  • 53
  • 99

5 Answers5

4

I think this should work

List<String> idList= employeeList.stream()
    .map(UserDto::getUserId)
    .filter(Objects::nonNull)
    .map(String::toUpperCase)
    .flatMap(s -> Arrays.stream(s.split(",")))//create a stream of split values
    .distinct()
    .collect(Collectors.toList());
Holger
  • 285,553
  • 42
  • 434
  • 765
Nithin
  • 683
  • 3
  • 11
  • 2
    See also [How to split a String into a Stream of Strings?](https://stackoverflow.com/a/40933002/2711488) – Holger Apr 17 '20 at 16:16
  • Thank you for commenting that wonderful answer. I'll also make a change to my answer. – Nithin Apr 17 '20 at 16:36
1

Just use the split(...) method of String and flatMap(...) to go from the stream of arrays to a stream of the elements inside the arrays:

List<String> idList = employeeList.stream()
                .map(UserDto::getUserId)
                .filter(Objects::nonNull)
                .map(userId -> userId.split(",")) //get from the comma separated list to an array of elements
                .flatMap(Arrays::stream) //transform the stream of arrays to a stream of the elements inside the arrays
                .map(String::toUpperCase)
                .distinct()
                .collect(Collectors.toList());
1

It is possible to split it by using and it's like

.map(ids -> ids.toUpperCase().split(","))

But If you wanna create new list with IDs you can just apply for
1st Solution

List<String> splitted = new ArrayList<>();
list.stream().filter(Objects::nonNull).forEach(it -> splitted.addAll(Arrays.asList(it.toUpperCase().split(","))));

2nd Solution

list.stream().filter(Objects::nonNull).map(it -> Arrays.asList(it.toUpperCase().split(","))).flatMap(Collection::stream).collect(Collectors.toList());
emredmrcn
  • 144
  • 1
  • 5
0

Here it is:

employeeList.stream()
.map(UserDto::getUserId)
.filter(Objects::nonNull)
.map(ids -> ids.split(","))
.flatMap(Arrays::stream)
.map(String::toUpperCase)
.distinct()
.collect(Collectors.toList());

Take a look at how FlatMap works ;)

Jeremias
  • 19
  • 1
  • 4
0

if you need to perform the splitting quite often and performance is of the essence and/or split by a more complex rule, like split by , and remove white spaces using the Pattern class should be considered:

Pattern splitter = Pattern.compile("\\s*,\\s*");
List<String> idList= employeeList.stream()
        .map(UserDto::getUserId)
        .filter(Objects::nonNull)
        .map(String::toUpperCase)
        .flatMap(s -> splitter.splitAsStream(s))
        .distinct()
        .collect(Collectors.toList());
pero_hero
  • 2,881
  • 3
  • 10
  • 24