Grouping the custom object list by properties using Java 8

假装没事ソ 提交于 2020-05-29 05:59:17

问题


I am learning many new features of lambda and wondering how can I group by my custom object list based on certain properties as key? For example, I have list of object like this in json.

[{ "account" : "checking", "source" : "BOA" }, { "account" : "checking", "source" : "TD" }, { "account" : "saving", "source" : "WS" } ]

I am looking for way to group using java 8 feature to get output like this (grouping source as comma separated for same account.

[{ "account" : "checking", "source" : "BOA, TD" }, { "account" : "saving", "source" : "WS" } ]

Thanks


回答1:


What about this solution

    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    import java.util.stream.Collectors;

    public class Data {

        public static void main(String ab[]) {
            List<Data> dataList = Arrays.asList(new Data("checking", "BOA"), new Data("checking", "TD")
                    , new Data("saving", "WS"));
            List<Data> newList = new ArrayList<>(dataList.stream()
            .collect(Collectors.toMap(Data::getAccount, d -> d, (d1, d2) -> new Data(d1.account, d1.source + ", " + d2.source)))
            .values());
            System.out.println("dataList = " + dataList);
            System.out.println("newList = " + newList);
        }

        private String account;
        private String source;

        Data(String account, String source) {
            this.account = account;
            this.source = source;
        }

        @Override
        public String toString() {//just override toString as json object with out using jon passer  
            return "{ \"account\" : \""+account+"\", \"source\" : \""+source+"\" }";
        }

        public String getAccount() {
            return account;
        }

        public void setAccount(String account) {
            this.account = account;
        }

        public String getSource() {
            return source;
        }

        public void setSource(String source) {
            this.source = source;
        }
    }



回答2:


You can use the java stream groupingBy


Map<String, String> resultMap= records.stream().
collect(groupingBy(Record::getAccount, mapping(Record::getSource, joining(","))));
public class Record {

String account;
String source; 

// constructors 
...

// getters
public String getAccount (){
return account;
}

public String getSource (){
return source;
}

//setters 
....

}



回答3:


Considering the object itself is named Dto having private fields account and source being instantiated with a constructor with both fields and they are available through getters, then you can use Collectors.toMap reducing values wrapped in Collectors.collectingAndThen extracting only the values from the newly created Map:

List<Dto> reducedList = list.stream().collect(
    Collectors.collectingAndThen(
        Collectors.toMap(
            Dto::getAccount,
            dto -> new Dto(dto.getAccount(), dto.getSource()),
            (d1, d2) -> new Dto(d1.getAccount(), String.join(", ", d1.getSource(), d2.getSource()))
            ),
        map -> new ArrayList<>(map.values())));

This solution is suspiciously similar to my answer for this question: Collectors.reducing to List. However, this question came earlier by 6 hours.



来源:https://stackoverflow.com/questions/61924108/grouping-the-custom-object-list-by-properties-using-java-8

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!