0

所以,

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

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

所以,我正在考虑的步骤是:

  1. 将两个 POJO 列表合二为一,因此我至少有 2 个大小相同的列表(整数和 POJO),我知道它们包含匹配的元素。
  2. 对生成的 POJO 列表进行排序以匹配 Integer 列表。

但是,对于第 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

4 回答 4

4

将您的值存储List<MyPojo>在 a 中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 评论,与其使用 a并查找using的List<Integer> values每个值,不如使用 a存储值和所需值的位置来加速搜索过程。因此,生成的算法应如下所示:pojo.getId()List#indexOfMap<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);
}
于 2013-08-05T14:27:16.813 回答
1

排序很昂贵,需要O(nlgn). 我会说使用 a按 idMap映射Pojos,然后MapList顺序从 s 中检索它们。这需要更多的内存,但应该更快:

    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. 循环Pojos 并按属性创建 a Map
  2. 循环遍历原始文件ListList通过查找Pojo.Map
于 2013-08-05T14:30:56.307 回答
1

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

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

于 2013-08-05T14:55:53.453 回答
0

分而治之,首先对两个列表进行独立排序,然后将它们合并在一起,每次迭代时比较两个列表的第一个元素(使用比较器)。这是最有效的方法。

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

于 2013-08-05T14:24:17.600 回答