Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Group by a filed and count the non null fields in java 8 [duplicate]

I try to use java 8 features.

I have a class

@Data
@NoArgsConstructor
@AllArgsConstructor
class User {
    private String pId;
    private String uId;
    private String price;
}

I have a list, I try to group by pId and count the non null uId and price. Example:

List<User> list =
Arrays.asList(
    new User ("p1", "u1", null),
    new User ("p1", "u2", "a"),
    new User ("p2", null, "b"),
    new User ("p2", null, "c"),
    new User ("p3", "u4", "d")
);

My expected output is

[
    { pId:"p1", uCount:2, priceCount:1 },
    { pId:"p2", uCount:0, priceCount:2 },
    { pId:"p3", uCount:1, priceCount:1 }
]

I tried like following

Map<String, Map<Object, Long>> collect =
    list.stream()
        .collect(
            Collectors.groupingBy(
                User ::getPId,
                Collectors.groupingBy(f -> f.getUId(), Collectors.counting())));

My final mapping class is

@Data
@NoArgsConstructor
@AllArgsConstructor
class Stat {
    private String pId;
    private Integer uCount;
    private Integer priceCount;
}

Since I'm new to java, I'm facing struggle to complete it, I tried my best. Is that possible to remove null filed and count?


1 Answers

Java 12+ solution

By using teeing collectors and filtering you can do like this:

Map<String, Detail> result = list.stream()
       .collect(Collectors.groupingBy(User::getpId, Collectors.teeing(
           Collectors.filtering(u -> u.getuId() != null, Collectors.counting()),
           Collectors.filtering(u -> u.getPrice() != null, Collectors.counting()),
           (uCount, priceCount) -> new Detail(uCount, priceCount)
        )));

and

class Detail{
  private long uCount;
  private long priceCount;
}

output:

{ p1=Detail{uCount=2, priceCount=1}, p2=Detail{uCount=0, priceCount=2}, p3=Detail{uCount=1, priceCount=1} }

like image 117
Hadi J Avatar answered Dec 23 '25 11:12

Hadi J



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!