Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to construct a Map using with object properties as key using java stream and toMap or flatMap

I have list of objects and need to create a Map have key is combination of two of the properties in that object. How to achieve it in Java 8.

public class PersonDTOFun {

    /**
     * @param args
     */
    public static void main(String[] args) {
        
        List<PersonDTO> personDtoList = new ArrayList<>();
        
        PersonDTO ob1 = new PersonDTO();
        
        ob1.setStateCd("CT");
        ob1.setStateNbr("8000");
        
        personDtoList.add(ob1);
        
        
       PersonDTO ob2 = new PersonDTO();
        
        ob2.setStateCd("CT");
        ob2.setStateNbr("8001");
        
        personDtoList.add(ob2);
        

        PersonDTO ob3 = new PersonDTO();
        
        ob3.setStateCd("CT");
        ob3.setStateNbr("8002");
        
        personDtoList.add(ob3);
        
     Map<String,PersonDTO> personMap = new HashMap<>();
    //personMap should contain 

Map<String, PersonDTO> personMap = personDtoList.stream().collect(Collectors.toMap(PersonDTO::getStateCd, 
                                                                                     Function.identity(),(v1,v2)-> v2));

    }

}

In the above code want to construct personMap with key as StateCd+StateNbr and value as PersonDTO. As existing stream and toMap function only support single argument function as key can't able to create a key as StateCd+StateNbr.

like image 936
springbootlearner Avatar asked Jul 17 '26 20:07

springbootlearner


2 Answers

as the two answers above, you can use the toMap function that gets 2 functions as input, the first one is the way to get a unique key, the second is how to get the data.

We prefer to hold the unique key in the class its self and to call the function for the key directly from that class using the Class::Method as the function for the keys, it makes the code much more readable instead of using nested lambda functions

so using WJS example:

Map<String, PersonDTO> personMap =
            personDtoList
            .stream()
            .collect(Collectors.toMap(p->p.getStateCd() + p.getStateNbr(), p->p));

Map<String, PersonDTO> personMap =
        personDtoList
        .stream()
        .collect(Collectors.toMap(PersonDTO::getUniqueKey, p->p));

Note that this is exactly the same as the above logic wise

like image 162
Yair Landmann Avatar answered Jul 20 '26 10:07

Yair Landmann


Try it like this.

  • The key argument to map is the key and a concatenation of the values you described.
  • The value is simply the object
Map<String, PersonDTO> personMap =
            personDtoList
            .stream()
            .collect(Collectors.toMap(p->p.getStateCd() + p.getStateNbr(), p->p));
  • If you believe you will have duplicate keys, then you have several choices include a merge function.
  • the one shown below preserves the value for the first key (existing) encountered.
Map<String, PersonDTO> personMap =
            personDtoList
            .stream()
            .collect(Collectors.toMap(p->p.getStateCd() + p.getStateNbr(), p->p,
             (existingValue, lastestValue)-> existingValue));
  • the next one saves all instances of PersonDTO and puts same key values in a list.
Map<String, List<PersonDTO>> personMap =
            personDtoList
            .stream()
            .collect(Collectors.groupingBy(p->p.getStateCd() + 
                                              p.getStateNbr()));
like image 45
WJS Avatar answered Jul 20 '26 10:07

WJS



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!