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

Java 如何根据给定的模式重新排列列表中的项目?,java,hibernate,postgresql,java-8,spring-data,Java,Hibernate,Postgresql,Java 8,Spring Data,我有一个ID列表,如下所示:5,3,2,4,1,然后我用该ID从数据库中查询项目。但它们来自DB,通常按id排序,我的意思是1,2,3,4,5。我需要重新排列它们,使其与ID列表的顺序相同。我怎样才能做到这一点 编辑:这是一个澄清,因为许多人似乎对这个问题感到困惑。ID列表用于查询数据库,例如: SELECT * FROM Foo WHERE id in (5, 3, 2, 4, 1) 生成的Foo对象列表的顺序与id列表的顺序不同。问题是如何获得与初始ID列表顺序相同的Foo对象列表。我认为

我有一个ID列表,如下所示:
5,3,2,4,1
,然后我用该ID从数据库中查询项目。但它们来自DB,通常按id排序,我的意思是
1,2,3,4,5
。我需要重新排列它们,使其与ID列表的顺序相同。我怎样才能做到这一点

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

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

生成的Foo对象列表的顺序与id列表的顺序不同。问题是如何获得与初始ID列表顺序相同的Foo对象列表。

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

public static void main(String[] args) {

    List<Integer> ids = Arrays.asList(5, 3, 2, 4, 1, 6);
    List<Foo> 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<Foo> sortResults1(List<Integer> ids, List<Foo> 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<Foo> sortedResults = new ArrayList<>(Arrays.asList(sortedResultsArray));
    sortedResults.removeAll(Collections.singleton(null));
    return sortedResults;
}

private static List<Foo> sortResults2(List<Integer> ids, List<Foo> results) {
    Collections.sort(results, Comparator.comparingInt(item -> ids.indexOf(item.getId())));
    return results;
}
注意:此处发现类似问题:
它有一个带有树形图的合理答案。

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

public static void main(String[] args) {

    List<Integer> ids = Arrays.asList(5, 3, 2, 4, 1, 6);
    List<Foo> 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<Foo> sortResults1(List<Integer> ids, List<Foo> 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<Foo> sortedResults = new ArrayList<>(Arrays.asList(sortedResultsArray));
    sortedResults.removeAll(Collections.singleton(null));
    return sortedResults;
}

private static List<Foo> sortResults2(List<Integer> ids, List<Foo> results) {
    Collections.sort(results, Comparator.comparingInt(item -> ids.indexOf(item.getId())));
    return results;
}
注意:此处发现类似问题:
它有一个合理的树形图。

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

Collections.sort(List);
例如,如果您想根据其他列表对列表进行排序,那么应该使用比较器

Collections.sort(secondList, new Comparator<Item>() {
public int compare(Item left, Item right) {
    return Integer.compare(firstList.indexOf(left.getId(), firstList.indexOf(right.getId());
}
});
Collections.sort(secondList,newcomparator(){
公共整数比较(项目左、项目右){
返回Integer.compare(firstList.indexOf(left.getId(),firstList.indexOf(right.getId());
}
});

注意:-此比较器效率不高,您应该使用hashmap来存储索引。

如果您只想对列表排序
5、3、2、4、1
,则可以使用

Collections.sort(List);
例如,如果您想根据其他列表对列表进行排序,那么应该使用比较器

Collections.sort(secondList, new Comparator<Item>() {
public int compare(Item left, Item right) {
    return Integer.compare(firstList.indexOf(left.getId(), firstList.indexOf(right.getId());
}
});
Collections.sort(secondList,newcomparator(){
公共整数比较(项目左、项目右){
返回Integer.compare(firstList.indexOf(left.getId(),firstList.indexOf(right.getId());
}
});
注意:-此比较器效率不高,应使用hashmap存储索引。

使用纯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
使用纯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遍仍然不理解您的问题不要使用排序依据?向我们展示您的尝试。如果您在DB中选择ID 5,DB将返回ID 5的数据。您是否同时请求不同ID的数据?我不理解否决票,这是一个很好的问题!唯一缺少的是代码示例e您自己尝试过的内容。由于为问题选择了标记,因此不清楚您是想让数据库按顺序返回行,还是想在以后对列表重新排序。在后一种情况下,所有这些特定于数据库的标记都已过时且具有误导性。请阅读您的问题5次,但仍不了解您的专业知识请不要使用
ORDER BY
?向我们展示您的尝试。如果您在DB中选择ID 5,DB将返回ID 5的数据。您是否同时请求不同ID的数据?我不理解否决票,这是一个很好的问题!唯一缺少的是您自己尝试过的代码示例。由于为t选择了标记他问,现在还不清楚,你是想让数据库按顺序返回行,还是想在以后重新排列列表。在后一种情况下,所有这些特定于数据库的标记都是过时的和误导性的。使用比较器是个好主意。但是firstList包含ID,对吗?如果是这样,那么你应该在中比较
firstListdexof(left.getId())、firstList、indexOf(right.getId())
是的,但我只是举了一个例子,因为问题不太清楚。无论如何,我会编辑我的答案。因为这是一个Java 8问题,所以可以将比较器实现为
comparator.comparingit(item->firstList.indexOf(item.getId())
。对于五个元素,没有理由担心性能,在这种情况下hashmap不会更快。对不起,我的错误是,我没有看到
java8
标记,我只是警告他如果有更多元素。使用比较器很好。但是firstList包含ID,对吗?如果是,那么你应该在dexof(left.getId())、firstList、indexOf(right.getId())是的,但我只是举了一个例子,因为问题不太清楚。无论如何,我会编辑我的答案。因为这是一个Java 8问题,所以可以将比较器实现为
comparator.comparingit(item->firstList.indexOf(item.getId())
。对于五个元素,没有理由担心性能,在这种情况下hashmap不会更快。对不起,我的错误是,我没有看到
java8
标记,我只是警告他如果有更多元素。你不能从
int[]创建
列表
使用
数组。asList
,但是手动创建数组已经过时,只需使用
列表id=Arrays.asList(5,3,2,4,1);
。顺便说一句,您可以使用
sortedResults.removall(Collections.singleton(null));
sortedResults.removeIf(Objects::isNull)删除所有
null
元素不必要的数组创建也适用于另一个
asList
调用:
results=Arrays.asList(new Foo(1),new Foo(8),…
。此外,您可以将数组转换为列表而不使用
null
表示为流操作:
返回Arrays.Stream(sortedResultsArray).filter(Objects::nonNull).collect(Collectors.toList());
我远离流,尤其是在其他人理解的代码中;-)再次感谢您的指针。您不能从
int[]创建
列表
使用
数组。asList
,但是手动创建数组已经过时,只需使用
列表id=Arrays.asList(5,3,2,4,1);
。顺便说一句,您可以使用
sortedResults.removall(Collec>)删除所有
null
元素