Java中如何合并两个列表

3

我需要在Java中合并两个列表。我有一个列表,其中包含一个具有名称和描述的VO。我有另一个具有相同VO类型的列表,其中包含名称和地址。 "名称"是相同的。我需要创建一个具有名称、地址和描述的VO的列表。

public class PersonDetails{
    private String name;
    private String description;
    private String address;
//getters and setters
}

有人能给我建议一下实现它的最佳方式吗?


你的两个列表大小相同吗?第一个列表中的每个元素都在第二个列表中,反之亦然吗?你的列表中每个元素都是唯一的吗? - Colin Hebert
@Colin HEBERT。两个列表的大小相同。第一个列表中的每个元素都在第二个列表中。例如,第一个列表具有PersonDetails VO,其名称为“John”且描述为“John's description”。第二个列表具有具有相同名称“John”和地址“Street1”的PersonDetails VO。我需要合并这两个列表,以便我有一个新列表,其中名称、地址和描述为“John”、“John Description”和“Street1”。 - Apps
5个回答

5

这要看情况:

如果两个列表包含完全相同的数据,您可以按名称对它们进行排序,迭代它们并设置缺失的属性。

如果不是,则将第一个列表放入Map中,以名称作为键。然后遍历第二个列表,在Map中查找VO并设置值。之后,只需再次从Map中获取所有值作为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;

}

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

将第一个列表的所有元素放入地图中,然后将第二个列表的内容合并到其中:

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());
    }
}

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;
    }
}

}

最好事先按名称对两个列表进行排序,这样可以使双重迭代更快。

好主意,但为什么不将数据从vo2写入vo1,这样可以节省很多对象创建。 - Sean Patrick Floyd
@seanizer 没错,但是这个例子只是为了给楼主提供一个使用双重循环的简单示例。 - nkr1pt

1

将列表转换为HashMap,使用名称字符串作为键。这样您就可以相当高效地合并数据。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接