简体   繁体   中英

Use of grouping by in java8 streams

I have a List of Event objects i want to transform to JSON.

An event is defined as below :

public class Event {

    private final String name;
    private final Date date;

    public Event(String name, Date date) {
        this.name = name;
        this.date = date;
    }

    public String getName() {
        return name;
    }

    public Date getDate() {
        return date;
    }
}

the code below :

List<Event> events = ...;
        SimpleDateFormat dayFormatter=new SimpleDateFormat("dd/MM/yyyy");
        Map<String,List<JsonNode>> result = events.stream().map(event -> {
            ObjectNode jsonMatch = jsonNodeFactory.objectNode();
            jsonMatch.put("name",event.getName());
            jsonMatch.put("day",dayFormatter.format(event.getDate()));
            return jsonMatch;
        }).collect(Collectors.groupingBy(item -> item.get("day").asText(),
                Collectors.toList()));

creates me a json that i want, which looks like this :

{
    "10/03/2014": [{name:"event1",day:"10/03/2014"},{name:"event2",day:"10/03/2014"}]
}

but to me, the day attribute in each event node is a redundant information that i want to bypass, in order to obtain this json :

{
        "10/03/2014": [{name:"event1"},{name:"event2"}]
    }

but if i dont put it in the object, i cant do a groupingby on it. Is there any workaround to make it happen?

Don't do the mapping step before the collect operation, do it only for the values of the groups.

SimpleDateFormat dayFormatter=new SimpleDateFormat("dd/MM/yyyy");
Map<String,List<JsonNode>> result = events.stream()
    .collect(Collectors.groupingBy(event -> dayFormatter.format(event.getDate()),
        Collectors.mapping(event -> {
            ObjectNode jsonMatch = jsonNodeFactory.objectNode();
            jsonMatch.put("name", event.getName());
            return jsonMatch;
        }, Collectors.toList())));

You can use Collectors.toMap() method:

Map<String,List<JsonNode>> result = events.stream()
    .map(event -> {
        ObjectNode jsonMatch = jsonNodeFactory.objectNode();
        jsonMatch.put("name",event.getName());
        jsonMatch.put("day",dayFormatter.format(event.getDate()));
        return jsonMatch;
    })  
    .collect(Collectors.toMap(
        item -> item.get("day").asText(),
        item -> new ArrayList<>(Arrays.asList(item.get("name"))),
        (i1, i2) -> {
            i1.addAll(i2);
            return i1;
        }
    ));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM