Petr Mensik
Petr Mensik

Reputation: 27496

Join data from two Lists into one object

I ran into following situation and I am wondering about best solution. Let's say I have List<Object1> and List<Object2>, these lists are result of two separated queries. Both of them have the same size and there is relationship 1:1 between elements in the lists based on ID. I know that best solution would be fetching data in one DB query but that's possible right now.

So my question is, what is the best way to join these lists into let's say List<Object3>?

Upvotes: 2

Views: 3049

Answers (5)

sp00m
sp00m

Reputation: 48807

I would use a BidiMap (see Apache Commons Collections).

Moreover, if you're sure the two lists have the same size and each id is present within the two lists, you could sort the list by the id and go through them with a classic for loop.

Comparator<YourObject> comparator = new Comparator<YourObject>() {
    @Override
    public int compare(YourObject o1, YourObject o2) {
        return o1.getId().compareTo(o2.getId());
    }
};

Collections.sort(list1, comparator);
Collections.sort(list2, comparator);

// import org.apache.commons.collections.BidiMap;
// import org.apache.commons.collections.bidimap.DualHashBidiMap;
BidiMap map = new DualHashBidiMap();

// required: list1.size() == list2.size()
for (int i = 0; i < list1.size(); i++) {
    map.put(list1.get(i), list2.get(i));
}

Upvotes: 1

Rahul Agrawal
Rahul Agrawal

Reputation: 8971

Use Apache Common BeanUtils as you don't have to write much code, also datatype convertions will be proper.

In this case both object1List and object2List should be in same order based on ID. To have that use Comparable interface to sort these based on ID for both Object1 and Object2

Example Code

Object1.java

public class Object1 implements Comparable<Object1>{

    private Integer id;
    private String name;
    private int quantity;


    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getQuantity() {
        return quantity;
    }
    public void setQuantity(int quantity) {
        this.quantity = quantity;
    }


    public int compareTo(Object1 compareObject1) { 
        int compareId = ((Object1) compareObject1).getId(); 
        //ascending order
        return this.id - compareId; 
    }   
}

Object2.java

public class Object2 implements Comparable<Object2>{

    private Integer id; 
    private double amount ;


    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public double getAmount() {
        return amount;
    }
    public void setAmount(double amount) {
        this.amount = amount;
    }

    public int compareTo(Object2 compareObject2) { 
        int compareId = ((Object2) compareObject2).getId(); 
        //ascending order
        return this.id - compareId; 
    }   
}

Object3.java which will have fields names same as Object1 and Object2.java

Actual Implementation

int cnt = 0;
List<Object3> object3List = new ArrayList<Object3>();
List<Object1> object1List = Collections.sort(object1List);
List<Object2> object2List =  Collections.sort(object2List);

for(Object1 obj1 : object1List) {
   BeanUtils.copyProperties(obj3, obj1);
   Object2 obj2 = object2List.get(cnt);
   BeanUtils.copyProperties(obj3, obj2);
   object3List.add(obj3);
   cnt ++;
}

Upvotes: 1

dan
dan

Reputation: 13262

If equals and hashCode are using the ID, and they should if this represents the uniqueness in your objects, you could also use sets instead of lists. This way you will be able to do something like set1.addAll(set2)

Upvotes: 0

Dunes
Dunes

Reputation: 40658

Make sure the queries order by id and then just iterate over the lists at the same time, whilst creating your new super list. This isn't foolproof, if the queries return differing sets of ids then the data will be corrupt. You could always add a check to make sure the ids match before adding the two objects to the super list though.

Upvotes: 1

Vikdor
Vikdor

Reputation: 24124

I would

  • convert the first list into Map with key as the ID and value as Object1.
  • iterate through the second list, get the object1 corresponding to the ID of object2.
  • perform the merge operation or whatever is intended and prepare object3 and put it in a list.

The resultant order would be that of in second list.

Upvotes: 4

Related Questions