2016-06-15 6 views
1

私はこのIDのリストを持っています:5, 3, 2, 4, 1、次にそのIDでDBからアイテムをクエリします。しかし、彼らは通常IDからソートされたDBから来て、私は1, 2, 3, 4, 5を意味します。 idsリストと同じ順序になるように並べ替える必要があります。どうすればそれを達成できますか?指定されたパターンに従ってリスト内のアイテムをどのように並べ替えるのですか?

編集:多くの人がこの質問について混乱しているように見えるので、解明。

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

のFooオブジェクトの結果のリストをIDのリストと同じ方法で順序付けられていない。IDのリストは、このような、例えば、データベースを照会するために使用されます。問題は、最初のIDリストと同じ順序でFooオブジェクトのリストを取得する方法です。

+1

は、あなたの質問を読んでまだ5回あなたの問題を理解していない – SpringLearner

+0

どういう意味ですか? – ThiepLV

+0

'ORDER BY'を使用しないでください。あなたが試したことを私たちに教えてください。 – Igoranze

答えて

2

私はあなたのコード内で、クエリの結果を再オーダーにあると思う:

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; 
} 

最初のソリューションは、IDのリストには存在しないIDを持つ任意の結果を省略します。

コンパレータを使用した2番目の解決策は、不明なIDを持つ結果を結果リストの前に置きます。

出力:

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

注:ここに同様の質問が見つかりました:Sort an (Array)List with a specific order それはTreeMapを持つ合理的な答えを持っています。

+1

'Arrays.asList'を使って' int [] '配列から' list'を作成することはできませんが、マニュアル配列の作成は時代遅れです。リスト ids = Arrays.asList(5,3,2 、4,1); '。ところで、 'sortedResults.removeAll(Collections.singleton(null));'または 'sortedResults.removeIf(Objects :: isNull);' – Holger

+0

ポインタのおかげで、すべての 'null'要素を取り除くことができます。私は答えを組み込みました –

+1

配列作成の不要性は、他の 'asList'呼び出しにも適用されます:' results = Arrays.asList(new Foo(1)、new Foo(8)、... '。ストリーム操作として 'null'を持たないリストへの配列の変換を表現する:' return Arrays.stream(sortedResultsArray).filter(Objects :: nonNull).collect(Collectors.toList()); ' – Holger

0

あなたは自分のリスト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()); 
} 
}); 

注:このコンパレータはあまり効率的ではありません。インデックスを格納するためにハッシュマップを使用する必要があります。純粋のPostgreSQLを使用して

+0

コンパレータの素晴らしいアイデア。しかしfirstListにはIDが含まれていますよね?もしそうなら、 'firstList、indexof(left.getId())、firstList、indexOf(right.getId()) 'を比較してください。 –

+0

ええ、しかし質問はあまり明確ではないので、とにかく私は自分の答えを編集します。 – Ravikumar

+1

これはJava 8の質問ですので、コンパレータを 'Comparator.comparingInt(item - > firstList.indexOf(item.getId()))'として実装することができます。 5つの要素については、パフォーマンスについて心配する必要はなく、その場合ハッシュマップは高速ではありません。 – Holger

2

バージョン> = 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 
+0

これはおそらく受け入れられる回答でしょう –

+0

@AdriaanKosterそれはビジネスロジックがどこにあるかによって異なります。メインクエリがJavaコードで自動生成されている場合など、Javaソリューションが優れています。 – Abelisto

+0

本当ですが、質問に 'hibernate'と' postgresql'というタグが付きました... –

関連する問題