2
firstlist
  .stream()
  .map( x -> { 
            return secondList
               .stream()
               .map( y -> { //return a string } )
               .collect(Collectors.toList()) // "Output" I need
              }
       )
    .//Get the "Output" here

I have two list. the item in first list have to compared with second list and new list have to built.

Sample Input

List 1 : [ { "id" ; 3, "names" : ["test","test2"] }]
List 2 : [ {"name": :"test" , "age" :3}]

Output:

List 3 : [ {"id" : 3, "name" : "test", "age" :3} ]

P.S: The names in first list should be checked against second list

9
  • 1
    can you show us some input output, your question is unclear Commented Aug 13, 2018 at 9:13
  • on what criteria are you merging? Commented Aug 13, 2018 at 9:23
  • 1
    Edited my question with sample input and output. Commented Aug 13, 2018 at 9:23
  • @madhairsilence could you pls share the POJO for both the lists ? Commented Aug 13, 2018 at 9:28
  • 1
    @madhairsilence idownvotedbecau.se/beingunresponsive -> you mostly ignore all the comments asking for clarification on the question and answers. If you want a usable solution you should learn to work with us, and provide us the information we need Commented Aug 13, 2018 at 11:12

4 Answers 4

5

You need something like this :

List<ObjectA> firstlist = new ArrayList<>();
firstlist.add(new ObjectA(3, Arrays.asList("test", "test2")));
List<ObjectB> secondList = new ArrayList<>();
secondList.add(new ObjectB("test", 3));

List<ObjectC> result = firstlist.stream()
        .flatMap(a -> secondList.stream()
                .filter(b -> a.getNames().contains(b.getName()))
                .map(c -> new ObjectC(a.getId(), c.getName(), c.getAge()))
        ).collect(Collectors.toList());

If I understand your question you have three Object different like this:

@Getter @Setter @AllArgsConstructor @NoArgsConstructor
public class ObjectA {
    private int id;
    private List<String> names;
}

@Getter @Setter @AllArgsConstructor @NoArgsConstructor
public class ObjectB {
    private String name;
    private int age;
}

//And the result Object you want to get
@Getter @Setter @AllArgsConstructor @NoArgsConstructor @ToString
public class ObjectC {
    private int id;
    private String name;
    private int age;
}

The outputs of this example is :

[ObjectC(id=3, name=test, age=3)]

For the annotation I'm using Lombok for that

Sign up to request clarification or add additional context in comments.

4 Comments

Somehow I get java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to ObjectC
@madhairsilence can you please show us how you fill your Lists? from the question I assumed that you use Objects not maps, so please edit your question and provide to us how you fill this lists, and about the error it is logic It seems you mix between my data type and your data type for that you get this error, I'm waiting for your edit.
OK. one small mistake. The actual error is I get java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to "ObjectA". And I face the exception exactly at "collect". If I remove that, the code works fine
Hi @madhairsilence listen carefully, can you please show us your code? I can't answer without seeing your code!
0

is it what you are looking for?

        firstList
            .stream()
            .filter(item -> secondList
                .stream().anyMatch(item::matches))
            .collect(Collectors.toList());

1 Comment

Looks close. But its not actual match. is the attribute from first list should match an attribute from second list
0

Your attributes are so general, I think you'd better introduce some custom class to replace the map and to meet your requirements, here is a simple demo for the input and output in your question as:

public class SimpleFlatMap {
    public static void main(String... args) {
        List<EntityWithNames> listOne = new ArrayList<>();
        listOne.add(new EntityWithNames());
        List<EntityWithAge> listTwo = new ArrayList<>();
        listTwo.add(new EntityWithAge("test", 3));
        List<EntityWithNameAndAge> listThree = listOne.stream().map(withNames -> {
            EntityWithAge entityWithAge = listTwo.stream()
                    .filter(withAge -> withNames.names.contains(withAge.name))
                    .findAny()
                    .orElse(new EntityWithAge());
            return new EntityWithNameAndAge(withNames.id, entityWithAge.name, entityWithAge.age);
        }).collect(Collectors.toList());
        System.out.println(listThree);
    }

    static class EntityWithNames {
        Long id;
        List<String> names;

        public EntityWithNames() {
            id = 3L;
            names = new ArrayList<>(Arrays.asList("test", "test1"));
        }
    }

    static class EntityWithAge {
        String name;
        int age;

        public EntityWithAge() {
            name = "default";
            age = -1;
        }

        public EntityWithAge(String name, int age) {
            this.name = name;
            this.age = age;
        }
    }

    static class EntityWithNameAndAge {
        Long id;
        String name;
        int age;

        public EntityWithNameAndAge(Long id, String name, int age) {
            this.id = id;
            this.name = name;
            this.age = age;
        }

        @Override
        public String toString() {
            return String.format("id: %d, name: %s, age: %d", id, name, age);
        }
    }
}

The output:

[id: 3, name: test, age: 3]

1 Comment

Would have preferred a sleeker version.
0

You might want the following:

List<ClassWithId>  list1 = new ArrayList<>();
List<ClassWithAge> list2 = new ArrayList<>();

list1.add(new ClassWithId(3, Arrays.asList("test", "test2")));
list2.add(new ClassWithAge("test", 4));

List<ClassResult> list3 = list2.stream()
                               .map(i -> new ClassResult(
                                               list1.stream()
                                                    .filter(j -> j.getList().contains(i.getName()))
                                                    .map(j -> j.getId())
                                                    .findFirst().get(), 
                                               i.getName(), i.getAge()))
                               .collect(Collectors.toList());

This solution assumes the structure of the following two input objects and the output object:

  • ClassWithId

    private int id;
    private List<String> list;
    
  • ClassWithAge

    private String name;
    private int age;
    
  • ClassResult

    private int id;
    private int age;
    private String name;
    

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.