基于整数列表对POJO集合进行排序

时间:2013-08-05 14:22:20

标签: java sorting collections

所以,

我有一种情况,我使用整数列表从不同的来源获取一些数据。因此,我得到两个列表,它们都具有相同的POJO类型作为内容,并且包含输入列表中的所有元素,但是按照未知顺序。

我需要的是让这些POJO按照与我的第一个列表相同的顺序排序(这个整数是POJO中带有getter / setter的字段),所以我得到一个带有POJO的List,其顺序与我的整数完全相同列表。

所以,我想到的步骤是:

  1. 将两个POJO列表合并为一个,所以我至少有两个相同大小的列表(Integer和POJO),我知道它们包含匹配的元素。
  2. 对生成的POJO列表进行排序以匹配整数列表。
  3. 然而,对于第2步,我需要找到好的(这意味着,有效和整洁)的方式来做到这一点......我正在考虑创建一个像这样的比较器:

    public class POJOComparable implements Comparator<MyPOJO>{
    
      private List<Integer> values;
    
      public POJOComparable(List<Integer> values) {
        this.values = values;
      } 
    
      @Override
      public int compare(MyPOJO o1P, MyPOJO o2P) {
          int o1 = values.indexOf(o1P.getId());
          int o2 = values.indexOf(o2P.getId());
          return (o1>o2 ? -1 : (o1==o2 ? 0 : 1));
      }
    } 
    

    现在,这是一个很好的方法来进行这样的排序还是有一些更好或更有效的方法来做到这一点?列表将包含大约20个项目,但这种排序将经常进行,因此我正在寻找有效的方法。

4 个答案:

答案 0 :(得分:4)

List<MyPojo>的值存储在TreeMap<Integer, MyPojo>中,并让此集合为您排序。一个简单的方法是:

TreeMap<Integer, MyPojo> aSortedMap = new TreeMap<Integer, MyPojo>();
for(MyPojo pojo : aListOfMyPojo) {
    aSortedMap.put(values.indexOf(pojo.getId()), pojo);
}

请注意,此方法假定每个pojo.getId()List<Integer> values内都有一个唯一值。


根据@BoristheSpider评论,不是使用List<Integer> values并使用pojo.getId()搜索List#indexOf的每个值,而是使用Map<Integer, Integer>来存储值pojo.getId()和所需的Integer值可加快搜索过程。因此,结果算法应如下所示:

//replace the List<Integer> by a Map<Integer>
Map<Integer, Integer> values = new HashMap<Integer, Integer>();
//store the pojo.getId() value with its associated int value
values.put(pojo.getId(), ...);

//...
TreeMap<Integer, MyPojo> aSortedMap = new TreeMap<Integer, MyPojo>();
for(MyPojo pojo : aListOfMyPojo) {
    aSortedMap.put(values.get(pojo.getId()), pojo);
}

答案 1 :(得分:1)

排序很昂贵,需要O(nlgn)。我会说使用Map按ID显示Pojo,然后按Map顺序从List中检索它们。这需要更多的记忆,但应该更快:

    final Map<Integer, Pojo> pojoMap = new HashMap<>(pojos.size(), 1f);
    for (final Pojo pojo : pojos) {
        pojoMap.put(pojo.id, pojo);
    }

    final List<Pojo> sortedPojos = new ArrayList<>(ids.size());
    for (final int id : ids) {
        sortedPojos.add(pojoMap.get(id));
    }

所以

  1. 循环Pojo并在属性旁边创建Map
  2. 在原始List上方循环,并在List中查找Pojo来填充新的Map

答案 2 :(得分:1)

更改POJO类以将索引包含为int。如果您一次只能订购数十个对象,那么浪费的空间就是微不足道的。获得的是简单性,直接性和降低混淆的风险。

比较器只查看每个对象中的一个字段 - 没有昂贵的列表搜索。

答案 3 :(得分:0)

划分并征服,首先将两个列表独立排序,然后将它们合并在一起,每次迭代时使用比较器比较两个列表的第一个元素。这是最有效的方式。

您可以使用默认的java排序对两个列表进行排序。