1

For loop code is this.

Param : ArrayList userList


Map<String, User> map = new HashMap();


for (User user : userList) {
    String[] arr = user.getStringSeq().split(DELIMITER);
    String key = String.join(DELIMITER, arr[MENU_IDX], arr[GROUP_IDX]);

    if (Objects.isNull(map.get(key))) {
        Set<IOType> ioTypeSet = new HashSet<>();
        ioTypeSet.add(IOType.valueOf(arr[IO_TYPE_IDX]));
        user.setIoTypes(ioTypeSet);
        map.put(key, user);
    } else {
        map.get(key).getIoTypes().add(IOType.valueOf(arr[IO_TYPE_IDX]));
    }
}

and i want to modify stream

List<List<user>> userList = userList
        .stream()
        .collect(groupingBy(
                e -> {
                    String[] arr = e.getStringSeq().split(DELIMITER);
                    return String.join(DELIMITER, arr[0], arr[1]);
                },
                mapping(e -> {
                    IOType ioType = IOType.valueOf(e.getNavAuthSeq().split(DELIMITER)[2]);
                    User user = new User();
                    user.addIoType(ioType);
                    return user;
                }, toList())
        )).values()
        .stream()
        .toList();

my stream code grouping list succefully but i want to remove same key element and put splited string like this


List<List<user>> userList = userList
        .stream()
        .collect(groupingBy(
                e -> {
                    String[] arr = e.getStringSeq().split(DELIMITER);
                    return String.join(DELIMITER, arr[0], arr[1]);
                },
                mapping(e -> {
                    if (e.getIoTypes() != null) {
                        e.getIoTypes().add(IOType.NONE);
                        return null;
                    } else {
                        IOType ioType = IOType.valueOf(e.getStringSeq().split(DELIMITER)[2]);
                        UserNavAuthsLoginDTO userNavAuthsLoginDTO = new UserNavAuthsLoginDTO();
                        userNavAuthsLoginDTO.addIoType(ioType);
                        return userNavAuthsLoginDTO;
                    }
                }, toList())
        )).values()
        .stream()
        .toList();

but if else code doesn't work can i resove this problem?

Alexander Ivanchenko
  • 25,667
  • 5
  • 22
  • 46

1 Answers1

0

If you want to discard certain elements after inside the Collector after groupingBy, you can wrap mapping() with Collector filtering(). It expects a Predicate and retains only elements for which predicate gets evaluated to true.

.collect(Collectors.groupingBy(
    e -> { },                        // classifier Function of groupingBy
    Collectors.filtering(e -> { },   // Predicate of filtering
        Collectors.mapping(e -> { }, // mapper Function of mapping
            Collectors.toList())
    )
))

Note that there's a difference between using filter() operation and Collector filtering(). Imagine a scenario when all elements mapped to a particular Key don't pass the predicate. In this case, the entry with this Key would be present in the resulting Map (and its Value would be an empty list). And if you apply filter() in the stream - there wouldn't be such entry.

Alternatively, if it's not important to filter out elements after the grouping phase, you can use filter() operation, that would be a preferred way in such case.

Also, worth to point out that you're performing side-effects on the mutable function parameter inside mapping() (to put it simple, anything that a function doesn't besides computing its resulting value is a side-effect). I'm not claiming that it will break things somehow, but it's definitely not very clean.

Alexander Ivanchenko
  • 25,667
  • 5
  • 22
  • 46