Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
569 views
in Technique[技术] by (71.8m points)

lambda - Java 8 : Iterate from 2 lists and create a Map<String, Custom Object>

I have a list of class A and class B with no duplicate elements. "code" attribute will be same across both class A and B. I want to convert them to Map<String, C> using java 8 streams. Please help

public class A {
    private String code;
    private boolean status;
    field 3...
    field 4..

 
}

public class B {
    private String code;
    private String location;
    field 5...
    field 5..
}

public class C {
    private String location;
    private boolean status;
}

List1 : [A(code=NY, status=false), A(code=NJ, status=true),A(code=TX, status=true), A(code=NM, status=false)]

List2 : [B(code=NY, location=NewYork), B(code=NJ, location=NewJersey),B( code=TX, location=Texas), B(code=NM, location=NewMexico)]

Map =  map{NY=C(location=NewYork, status=false), NJ=C(location=NewJersey, status=true), TX=C(location=Texas, status=true),NM=C(location=NewMexico, status=false)}


Final map should be in the same order as the elements in List1

~A

UPDATE : i updated the code to below, but its not compiling. any idea about whats wrong?

package test;

import java.util.*;
import java.util.stream.Collectors;

public class Test {

    static void main(String[] args){


        new Test().testFunction();

    }

      void testFunction(){


        System.out.println("Hello World");



        List<A> listA = Arrays.asList(new A("NY", false), new A("NJ", true), new A("TX", false), new A("AZ", true));
        List<B> listB = Arrays.asList(new B("NY", "New York"), new B("NJ", "New Jersey"),
                new B("TX", "Texas"), new B("NM", "New Mexico"));


        Map<String, B> mapB = listB
                .stream()
                .collect(Collectors.toMap(B::getCode, b -> b, (b1, b2) -> b1));

        Map<String, C> innerJoin = listA
                .stream()
                .filter(a -> mapB.containsKey(a.getCode())) // make sure a B instance exists with the code
                .map(a -> Map.entry(a.getCode(), new C(mapB.get(a.getCode()).getLocation(), a.getStatus())))
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (c1, c2) -> c1, HashMap::new));

        innerJoin.forEach((code, c) -> System.out.println(code + " -> " + c));

    }

}


     class A {
        private String code;
        private boolean status;

         public A(String code, boolean status) {
             this.code = code;
             this.status = status;
         }
         public String getCode() {
             return this.code;
         }
         public boolean getStatus() {
             return this.status;
         }
     }

     class B {
        private String code;
        private String location;

         public B(String code, String location) {
             this.code = code;
             this.location = location;
         }

         public String getCode() {
             return this.code;
         }
         public String getLocation() {
             return this.location;
         }
     }

     class C {
        private String location;
        private boolean status;

         public C(String location, boolean status) {
             this.location = location;
             this.status = status;
         }
         public String getLocation() {
             return this.location;
         }
         public boolean getStatus() {
             return this.status;
         }
    }

question from:https://stackoverflow.com/questions/65932654/java-8-iterate-from-2-lists-and-create-a-mapstring-custom-object

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You should use somethins like:

Map<String, B> mapList2 = list2.stream().collect(Collectors.toMap(B::getCode, 
    Function.identity()); // create temporary map

Map<String,B> result = list1.stream().collect(
            LinkedHashMap::new,
            (map, a) -> map.put(
                   a.getCode(), // get code from A
                   new C(
                           mapList2.get(a.getCode()).getLocation() // get location from B
                           a.getStatus() // get status from A
                   ),  
             Map::putAll); // use LinkedHashMap to keep order       

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...