如何根据给定的模式重新排列列表中的项目?

我有id列表,如下所示:5,3,2,4,1,然后我用DB查询DB中的项目。 但它们来自DB通常按id排序,我的意思是1, 2, 3, 4, 5 。 我需要将它们重新排列为与它们列出的顺序相同。 我怎样才能实现这一目标?

编辑:澄清,因为许多人似乎对这个问题感到困惑。 ID列表用于查询数据库,例如:

 SELECT * FROM Foo WHERE id in (5, 3, 2, 4, 1) 

生成的Foo对象列表的排序方式与ID列表的排序方式不同。 问题是如何获取与初始ID列表具有相同顺序的Foo对象列表。

我认为你必须在代码中重新排序查询的结果:

 public static void main(String[] args) { List ids = Arrays.asList(5, 3, 2, 4, 1, 6); List results = Arrays.asList(new Foo(1), new Foo(8), new Foo(2), new Foo(4), new Foo(5), new Foo(7)); System.out.println("sortResults1: " + sortResults1(ids, results)); System.out.println("sortResults2: " + sortResults2(ids, results)); } private static List sortResults1(List ids, List results) { Foo[] sortedResultsArray = new Foo[ids.size()]; for (Foo result : results) { // look up the required position of this result's id int pos = ids.indexOf(result.getId()); if (pos >= 0) { sortedResultsArray[pos] = result; } } List sortedResults = new ArrayList<>(Arrays.asList(sortedResultsArray)); sortedResults.removeAll(Collections.singleton(null)); return sortedResults; } private static List sortResults2(List ids, List results) { Collections.sort(results, Comparator.comparingInt(item -> ids.indexOf(item.getId()))); return results; } 

第一种解决方案省略了任何带有ID的结果,该ID不会出现在ID列表中。

使用比较器的第二个解决方案将任何带有未知ID的结果放在结果列表的前面。

输出:

 sortResults1: [Foo 5, Foo 2, Foo 4, Foo 1] sortResults2[Foo 8, Foo 7, Foo 5, Foo 2, Foo 4, Foo 1] 

注意:在这里找到一个类似的问题: 使用特定顺序对(数组)列表进行排序它对TreeMap有一个合理的答案。

使用纯PostgreSQL,

版本> = 9.5:

 select * from foo where id = any(array[5,3,2,4,1]) order by array_position(array[5,3,2,4,1], id); 

版本> = 9.4:

 with lst(i,n) as (select * from unnest(array[5,3,2,4,1]) with ordinality) select foo.* from foo join lst on (foo.id = lst.i) order by lst.n 

版本> = 8.4:

 with lst(i,n) as (select *, row_number() over () from unnest(array[5,3,2,4,1])) select foo.* from foo join lst on (foo.id = lst.i) order by lst.n 

如果您只想对列表5,3,2,4,1进行排序,那么您可以使用

 Collections.sort(List); 

如果要根据其他列表对列表进行排序,则应使用比较器

 Collections.sort(secondList, new Comparator() { public int compare(Item left, Item right) { return Integer.compare(firstList.indexOf(left.getId(), firstList.indexOf(right.getId()); } }); 

注意: – 这个比较器效率不高,你应该使用hashmap来存储索引。