Search code examples
javalisthashmapjava-streampredicate

Java 8 Streams - How to get an equivalent of partitioningBy() with Integer keys?


In the code shown below, p is a predicate of type Predicate<String>.

Map<Boolean, List<String>> partitioned = numbers.stream()
    .collect(Collectors.partitioningBy(p));

Is it possible to convert the boolean keys to the int type inside the partitioning logic rather than having another stream?

Looks like it could be done with grouping.

Map<String, List<String>> targetTableColumnListMap = nqColumnMapList.stream()
    .flatMap(m -> m.entrySet().stream())
    .collect(Collectors.groupingBy(
        e -> e.getKey().toUpperCase(), 
        Collectors.mapping(Map.Entry::getValue, Collectors.toList())
    ));

Solution

  • You could use the terminal operation collect(Collectors.toMap()) to group by your predicate and instead of returning its boolean value as the key you could use a ternary operator to return either 1 or 0.

    to convert the boolean keys to the int type

    Then, you could map to that key a List built on the String you tested the Predicate with, and to handle the colliding cases you could add the List associated to the second key into the List corresponding to the first key.

    Here's a snippet of the code:

    //My silly test Predicate
    Predicate<String> p = s -> s.length() > 4;
    
    //Mapping the numbers list
    Map<Integer, List<String>> partitioned = numbers.stream()
            .collect(Collectors.toMap(s -> p.test(s) ? 1 : 0, 
                s -> new ArrayList<>(List.of(s)), 
                (list1, list2) -> {
                    list1.addAll(list2);
                    return list1;
                }
            ));
    

    Here, there's also a link to test the code:

    https://ideone.com/Kd8xrI