我需要加入Java中的两个列表。我有一个列表,其中有一个名称和描述的VO。我有另一个列表,它具有相同的VO类型,具有名称和地址。 “名字”是一样的。我需要创建一个包含此VO的List,它包含名称,地址和描述。 VO结构是
public class PersonDetails{
private String name;
private String description;
private String address;
//getters and setters
}
有人可以建议我最佳方式来实施吗?
答案 0 :(得分:5)
取决于:
如果列表包含完全相同的数据,您可以按名称对它们进行排序,迭代它们以设置缺少的属性。
如果没有,我会将第一个列表放在Map中,名称为key。然后迭代第二个列表,在地图中查找VO并设置值。 之后,只需将所有值作为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());
}
如果列表包含两个相同的VO(名称相同),则可以使用此。
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;
}
答案 1 :(得分:2)
我会按源名将源VO列表的每个列表放在一个映射中,创建一组两个键,迭代它并将目标VO添加到结果列表中。
在示例代码中,VO是目标VO,VOD是仅包含描述的源VO,VOA是仅具有地址的源VO:
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);
}
答案 2 :(得分:2)
将第一个列表的所有元素放在地图中,然后将第二个列表的内容合并到其中:
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());
}
}
答案 3 :(得分:1)
从列表转到HashMap,使用名称字符串作为键。因此,您可以非常有效地合并数据。
答案 4 :(得分:1)
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;
}
}
}
最好事先在名称上对两个列表进行排序,这样可以加快双重迭代。