6

I want to get an intersection and union of two Lists of different types. I have been trying using Java 8 streams because I think this is the easiest way to do it. So far I have failed each time.

I have simplified the code so it can easily be reproduced. I have two objects, Data1 and Data2.

For example:

public class Data2 {    
    private int id;
    private String name;
    private String type;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public Data2(int id, String name, String type) {
        this.id = id;
        this.name = name;
        this.type = type;
    }

}

public class Data1 {

    private int id;
    private String name;
    private int amount;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAmount() {
        return amount;
    }

    public void setAmount(int amount) {
        this.amount = amount;
    }

    public Data1(int id, String name, int amount) {
        this.id = id;
        this.name = name;
        this.amount = amount;
    }
}

public class OutputData {
    private int id;
    private String name;
    private String type;
    private int amount;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public int getAmount() {
        return amount;
    }

    public void setAmount(int amount) {
        this.amount = amount;
    }

    public OutputData(int id, String name, String type, int amount) {

        this.id = id;
        this.name = name;
        this.type = type;
        this.amount = amount;
    }

}

They have similar fields.. I need to intersect them based on ID (intersect) and store them in an output (union?) of type OutputData.

Example of a main type:

List<Data2> listOfData2 = new ArrayList<Data2>();

    listOfData2.add(new Data2(10501, "JOE"  , "Type1"));
    listOfData2.add(new Data2(10603, "SAL"  , "Type5"));
    listOfData2.add(new Data2(40514, "PETER", "Type4"));
    listOfData2.add(new Data2(59562, "JIM"  , "Type2"));
    listOfData2.add(new Data2(29415, "BOB"  , "Type1"));
    listOfData2.add(new Data2(61812, "JOE"  , "Type9"));
    listOfData2.add(new Data2(98432, "JOE"  , "Type7"));
    listOfData2.add(new Data2(62556, "JEFF" , "Type1"));
    listOfData2.add(new Data2(10599, "TOM"  , "Type4"));


List<Data1> listOfData1 = new ArrayList<Data1>();

    listOfData1.add(new Data1(10501, "JOE"    ,3000000));
    listOfData1.add(new Data1(10603, "SAL"    ,6225000));
    listOfData1.add(new Data1(40514, "PETER"  ,2005000));
    listOfData1.add(new Data1(59562, "JIM"    ,3000000));
    listOfData1.add(new Data1(29415, "BOB"    ,3000000));

Here is one of my best attempts at this, with no success and lots of errors:

List<OutputData> od = 
  listOfData1.stream()
             .flatMap(x -> listOfData2.stream()
                                      .filter(y -> x.getId().equals(y.getId()))
             .map(y -> new OutputData(x.getId(), x.getName(), y.getType(), x.getAmount()))
             .collect(Collectors.toList()));

This should return a List<OutputData> that has one entry of ID 10603, name SAL and all other fields populated.

2
  • Are you using Guava? Commented Dec 16, 2016 at 20:28
  • I am not, but I would be open to it Commented Dec 16, 2016 at 20:38

2 Answers 2

7

This should do it, but in the example there are 5 records in each list that have same ids.

List<OutputData> result = listOfData1.stream()
        .flatMap(x -> listOfData2.stream()
                .filter(y -> x.getId() == y.getId())
                .map(y -> new OutputData(y.getId(), x.getName(), y.getType(), x.getAmount())))
        .collect(Collectors.toList());
Sign up to request clarification or add additional context in comments.

1 Comment

I just realized my test cases were wrong. I am going to test this out and will let you know
0

I'll give you some pseudo code:

declare list 3 (type data3)

for i = length of list 1
  for j = length of list 2
    if list1[i].getid == list2[j].getid
      new data3 object with all relevant fields
      add to list 3

2 Comments

Thanks for the pseudo code. I am able to do it no problem with regular loops. I wanted to do it using java 8 streams though
No problem. I was wondering why you were using a more complicated solution than necessary. Cheers!

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.