Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 streams - How do I manipulate value in a group by result?

I have a list of objects with two String fields like

Name1, Active
Name2, InActive
Name3, InActive
Name4, Active

And I would like to have a

Map<Boolean, List<String>>

where Active=true and InActive=false.

I tried

active = dualFields.stream().collect(
       Collectors.groupingBy( 
           x -> StringUtils.equals(x.getPropertyValue(), "Active")));

But I received

Map<Boolean, List<DualField>>
like image 913
Bick Avatar asked Oct 02 '17 10:10

Bick


People also ask

How does Groupby work in Java 8?

In Java 8, you retrieve the stream from the list and use a Collector to group them in one line of code. It's as simple as passing the grouping condition to the collector and it is complete. By simply modifying the grouping condition, you can create multiple groups.

How do you use Groupby in Java?

The groupingBy() method of Collectors class in Java are used for grouping objects by some property and storing results in a Map instance. In order to use it, we always need to specify a property by which the grouping would be performed. This method provides similar functionality to SQL's GROUP BY clause.

Are Java 8 streams lazy?

The Java 8 Streams API is fully based on the 'process only on demand' strategy and hence supports laziness. In the Java 8 Streams API, the intermediate operations are lazy and their internal processing model is optimised to make it being capable of processing the large amount of data with high performance.

What is flatMap in Java stream?

Stream flatMap(Function mapper) returns a stream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element. Stream flatMap(Function mapper) is an intermediate operation. These operations are always lazy.


2 Answers

First of all, you can use partitioningBy, which is a special case of groupingBy (where you are grouping by a Predicate into two groups). You can map the objects to the required Strings with mapping.

I'm assuming you want the List<String> to contain the values of the second property (i.e. not getPropertyValue(), which contains "Active" or "InActive"):

Map<Boolean,List<String>> map =
    dualFields.stream()
              .collect(Collectors.partitioningBy(x -> StringUtils.equals(x.getPropertyValue(), "Active"),
                                                 Collectors.mapping(DualField::getSecondPropertyValue,
                                                                    Collectors.toList()));
like image 129
Eran Avatar answered Nov 15 '22 07:11

Eran


If you want your List<String> to be composed of propertyValue, than:

active = dualFields.stream().collect(
        Collectors.groupingBy( 
            x -> StringUtils.equals(x.getPropertyValue(), "Active"),
            Collectors.mapping(DualField::getPropertyValue, Collectors.toList());
            ));
like image 32
Eugene Avatar answered Nov 15 '22 08:11

Eugene