【问题标题】:Update a List with another subset List用另一个子集列表更新列表
【发布时间】:2013-11-30 17:26:11
【问题描述】:

我有一个简单的对象类,它有两个字段:id & name

public class MyObject{
   private int id; //unique id for each instance of MyObject
   private String name;

   //Setter & Getter
   ...
}

现在我有两个List 实例,每个实例都拥有ListMyObject

 /*it holds a list of MyObject*/
 List<MyObject> list_origin = GET_MyObject1();

 /*it holds a subset of above list, moreover, the subset objects with the 
   same 'id' as objects in above list have different 'name' value*/
 List<MyObject> list_update = GET_MyObject2();

list_update 实际上拥有list_origin子集,但已更新(不同)name 值。

现在,我需要用list_update 更新list_origin(即将list_origin 中的对象替换为list_update 中的对象),最有效的方法是什么?

【问题讨论】:

  • 如何将子集放入list_update
  • 不管我是怎么得到的,和我的问题无关。
  • 而不是 List> 为什么不使用 Map 并键入每个列表? List> 将是 O(n^2)
  • 如果我可以选择使用地图,我不会在这里问。
  • @Amir Afghani,我要问的是我在上面发布的内容,我不希望有人能读懂我的想法,这就是为什么我告诉你“如果使用地图可以是我的选择,我不会问这里”,告诉你我的情况下使用 Map 是开箱即用的有什么问题?

标签: java performance list jakarta-ee


【解决方案1】:

如果使用List.subList 方法获得list_update,则不必关心更新,因为两个列表将指向同一个公共对象(将共享引用)。

如果没有,我会考虑使用Map&lt;Integer, String&gt; 实例而不是List&lt;MyObject&gt; 实例:

Map<Integer, String> list_origin = GET_MyObject1();
Map<Integer, String> list_update = GET_MyObject2();
for(Entry<Integer, String> entry : list_update.entrySet()){
    list_origin.put(entry.getKey(), entry.getValue());
}

【讨论】:

    【解决方案2】:

    嗯,整个过程很可能:

    1. 遍历list_update的每个元素
    2. 对于list_update的每个元素,找到与id-int变量匹配的list_origin对应元素的索引。使用ArrayList.set(index, E) 方法更新元素。

    这总共需要 O(n^2) 费用。

    优化:

    1. 通过实现Comparable&lt;MyObject&gt; 使您的MyObject 类具有可比性
    2. Collection.sort(list_origin)对列表list_origin进行排序
    3. 然后在其上使用Collections.binarySearch(list, key)方法查找索引 目标对象和更新结果。

    这需要总共花费 O(nlogn)

    例如,您的 MyObject 类将是:

    class MyObject implements Comparable<MyObject>{
       private int id; 
       private String name;
    
        public MyObject(int x, String name) {
            this.id = x;
            this.name = name;
        }
    
        public void updateName(String name)
        {
            this.name = name;
        }
    
    
        @Override
        public int compareTo(MyObject o) {
           return Integer.compare(id, o.id);
        }
    
    }
    

    然后更新list_origin:

    Collections.sort(list_origin);
    
    for(MyObject obj: list_update)
    {
        int indx = Collections.binarySearch(list_origin, obj);
        list_origin.set(indx, obj);
    }
    

    【讨论】:

    • 谢谢,我会检查 Collections.binarySearch(list, key) 方法。
    • @Mellon,如果现在对您更有意义,请检查答案。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-24
    • 1970-01-01
    • 2021-06-20
    相关资源
    最近更新 更多