sorted で並び替え
並べ替えたら、呼び出し元のリストまで並んでいた
リストを並べ替えるとき、まず思いつくのは Collections.sort です。
Java
public static void printRanking(List<Integer> scores) {
Collections.sort(scores);
System.out.println(scores);
}これは動きますが、scores そのものを並べ替えてしまいます。呼び出した側が「表示してもらっただけ」のつもりでいると、次の行で元の順番を使おうとしたときに、もう元の順番は残っていません。表示のためのメソッドが、渡されたデータを黙って書き換える形になっています。
Stream の sorted() は、この問題が起きません。
Java
List<Integer> ranking = scores.stream().sorted().toList();
System.out.println(scores); // 渡されたときのままsorted() は並べ替えた新しい Stream を返すだけで、元のリストには指 1 本触れません。「並んだ結果が欲しい」と「元を並べ替えたい」は別の要求で、前者なら sorted() の方が安全です。
引数なしなら自然順、渡せば好きな順
sorted() を引数なしで呼ぶと、その型が元から持っている順番で並びます。数値なら小さい順、文字列なら辞書順です。これを自然順と呼びます。
自然順で困るのは、自作クラスを並べたいときです。会員をどう並べるべきかは Java には分かりません。そこで、比べ方そのものを渡します。
Java
List<Member> byAge = members.stream()
.sorted(Comparator.comparing(m -> m.age))
.toList();Comparator.comparing には「何で比べるか」を取り出す式を渡します。ここでは年齢を取り出しているので、年齢の小さい順に並びます。大きい順にしたいときは、後ろに .reversed() を付けます。
Java
.sorted(Comparator.comparing(m -> m.age).reversed())同じ年齢の人の中では名前順にしたい、というときは .thenComparing(...) をつなぎます。比べ方を組み立ててから渡す、という形はどれも同じです。
並べ方を渡さないと、実行時に落ちる
自作クラスの Stream に、引数なしの sorted() を呼んだときが要注意です。
Java
members.stream().sorted().toList(); // ClassCastExceptionこれはコンパイルは通ります。sorted() は自然順があることを前提にしているだけで、コンパイラはその有無を確かめてくれないからです。比べ方を持っていないクラスを並べようとした瞬間、実行時に ClassCastException が出ます。
数値や文字列を並べるときは引数なし、自作クラスを並べるときは
Comparatorを渡す、と覚えておけば、この例外にはまず出会いません。
やってみよう
Solution.sortedJoined(int[] arr) を完成させて、配列を昇順に並べた , 区切りの文字列を返してください。
Arrays.stream(arr) で IntStream を作り、sorted() で並べ替えます。int の自然順は小さい順なので、引数は要りません。並べ終わったら文字列の Stream に変えて、前の回で使った Collectors.joining(",") でつなぎます。
配列が空のときは空文字列を返します。同じ値が 2 回入っていても取り除く必要はありません。[3, 1, 1] なら 1,1,3 と、1 が 2 つ並んだまま出るのが正解です。
要件
- クラス名は
Solution、メソッド名はsortedJoined、引数はint[] arrひとつにすること - 戻り値の型は
Stringで、Stream API のsorted()を使って昇順に並べ替え、,区切りの 1 つの文字列にして返すこと - 配列が空 (
arr.length == 0) のときは空文字列""を返すこと
入出力例
sortedJoined([3,1,4,1,5,9,2,6]) → "1,1,2,3,4,5,6,9"
sortedJoined([]) → ""
sortedJoined([5]) → "5"
sortedJoined([1,2,3,4,5]) → "1,2,3,4,5"
sortedJoined([9,7,5,3,1]) → "1,3,5,7,9"
sortedJoined([-1,-5,0,3,-2]) → "-5,-2,-1,0,3"
sortedJoined([7,7,7,7]) → "7,7,7,7"