Reputation: 27496
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
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
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
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
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
Reputation: 24124
I would
The resultant order would be that of in second list.
Upvotes: 4