Reputation: 3389
I need to join two Lists in Java. I've a list which has a VO that has a name and description. I've another list which has same VO type that has name and Address. The "name" is same. I need to create a List with this VO which has both name, address and description. The VO structure is
public class PersonDetails{
private String name;
private String description;
private String address;
//getters and setters
}
Can someone please suggest me the best way to implement it?
Upvotes: 3
Views: 7899
Reputation: 406
It depends:
If the lists contain both exactly the same data, you can sort them both by name, iterate over them en set the missing property.
If not, I would put the first list in a Map, with the name as key. Then iterate over the second list, look in the map for the VO and set the value. After that, just get all the value's out of the map again as a List.
public List<Vo> merge(List<Vo> list1, List<Vo> list2) {
Map<String, Vo> tempMap = new HashMap<String, Vo>();
for (Vo v : list1) {
tempMap.put(v.name, v);
}
for (Vo vv : list2) {
//The if is in case the 2 lists aren't filled with the same objects
if (tempMap.containsKey(vv.name)) {
tempMap.get(vv.name).description = vv.description;
} else {
tempMap.put(vv.name, vv);
}
}
return new ArrayList<Vo>(tempMap.values());
}
If the lists contain both EXACT the same VO (equal by name), you can use this.
public List<Vo> merge(List<Vo> list1, List<Vo> list2) {
Collections.sort(list1, new Comparator<Vo>() {
public int compare(Vo o1, Vo o2) {
return o1.name.compareTo(o2.name);
}
});
Collections.sort(list2, new Comparator<Vo>() {
public int compare(Vo o1, Vo o2) {
return o1.name.compareTo(o2.name);
}
});
for(int i = 0; i < list1.size(); i++){
list1.get(i).description = list2.get(i).description;
}
return list1;
}
Upvotes: 5
Reputation: 298818
Put all elements of the first list in a map, then merge the contents of the second list into it:
final List<PersonDetails> listWithAddress =
new ArrayList<PersonDetails>();
final List<PersonDetails> listWithDescription =
new ArrayList<PersonDetails>();
// fill both lists with data
final Map<String, PersonDetails> map =
// map sorted by name, change to HashMap otherwise
// (or to LinkHashMap if you need to preserve the order)
new TreeMap<String, PersonDetails>();
for(final PersonDetails detailsWithAddress : listWithAddress){
map.put(detailsWithAddress.getName(), detailsWithAddress);
}
for(final PersonDetails detailsWithDescription : listWithDescription){
final PersonDetails retrieved =
map.get(detailsWithDescription.getName());
if(retrieved == null){
map.put(detailsWithDescription.getName(),
detailsWithDescription);
} else{
retrieved.setDescription(detailsWithDescription.getDescription());
}
}
Upvotes: 2
Reputation: 20594
I would put each list of the source VO lists in a map by name, create a set of both keys, iterate it and add a target VO to the result list.
In the example code, VO is the target VO, VOD is the source VO with description only, VOA is the source VO with address only:
List<VOD> descriptions = ...;
List<VOA> addresses = ...;
Map<String,String> description ByName = new HashMap<String,String>();
for (VOD description : descriptions) {
descriptionByName.put(description.name, description.description);
}
Map<String,String> addressByName = new HashMap<String,String>();
for (VOA address: addresses ) {
addressByName.put(address.name, address.address);
}
Set<String> allNames = new HashSet<String>();
allNames.addAll(descriptionByName.keySet());
allNames.addAll(addressByName.keySet());
List<VO> result = new ArrayList<VO>();
for (String name : allNames) {
VO one = new VO();
one.name = name;
one.address = addressByName.get(name)
one.description = descriptionByName.get(name)
result.add(one);
}
Upvotes: 2
Reputation: 4666
List<VO> list = new ArrayList<VO>();
for (VO vo1 : vo1List) {
for (VO vo2 : vo2List) {
if (vo1.getName().equals(vo2.getName())) {
VO newVo = new VO();
newVO.setName(vo1.getName());
newVO.setDescription(vo1.getDescription());
newVO.setAddress(vo2.getAddress);
list.add(newVO);
break;
}
}
}
It's best that you sort both lists on name beforehand, it makes the double iteration faster.
Upvotes: 1
Reputation: 11808
Go from list to HashMap, use the name string as key. So you can merge you data quite efficient.
Upvotes: 1