Java のソートはComparator で昇順、降順を指定
Java8 からソートは、 Comparatorインターフェースで 昇順、降順を手軽に指定できるようなのでメモ。
環境
-
Windows7 64bit
-
Java8(javac 1.8.0_60)
-
Arrays.sortの場合
配列のソートには、Arrays.sort()
が使える。
Arrays.sortの場合(プリミティブ型の配列)
import java.util.Arrays;
する必要がある。 昇順に並べ替えることができる。int などのプリミティブ型は昇順にしか並べ替えることができない。
クイックソートが使われている模様。
import java.util.Arrays;
int array[] = {3, 2, 1, 5, 4};
Arrays.sort(array);
System.out.println(Arrays.toString(array));
result:
[1, 2, 3, 4, 5]
参考:http://docs.oracle.com/javase/jp/8/docs/api/java/util/Arrays.html#sort-int:A-
Arrays.sortの場合(Comparatableを実装した配列)
Integer などComparatable を実装した配列では、 関数型インターフェースComparator(比較関数)を使用して昇順、降順を指定できる。
参考:Comparator (Java Platform SE 8)
昇順は、Comparator.naturalOrder()
を、 降順は、Comparator.reverseOrder()
を指定すればいい。
参考:http://docs.oracle.com/javase/jp/8/docs/api/java/util/Comparator.html#naturalOrder--
import java.util.Arrays;
import java.util.Comparator;
Integer array[] = {3, 2, 1, 5, 4};
Arrays.sort(array, Comparator.naturalOrder()); // 昇順になる
System.out.println(Arrays.toString(array));
result:
[1, 2, 3, 4, 5]
Arrays.sort(array, Comparator.reverseOrder()); // 降順になる
System.out.println(Arrays.toString(array));
result:
[5, 4, 3, 2, 1]
参考:http://docs.oracle.com/javase/jp/8/docs/api/java/util/Arrays.html#sort-T:A-java.util.Comparator-
Collections.sort の場合
Collections.sort()
の場合でも同様。 Collection型はプリミティブ型が使えないので、 Comparatable が実装されている型であれば、 Comparator で昇順と降順ができる。
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
List<Integer> list = new ArrayList<Integer>();
Collections.addAll(list, 3, 2, 1, 4, 5);
Collections.sort(list); // 未指定ならば昇順
System.out.println(list.toString());
result:
[1, 2, 3, 4, 5]
参考:http://docs.oracle.com/javase/jp/8/docs/api/java/util/Collections.html#sort-java.util.List-
Collection型オブジェクト自体でもsort 関数が呼べる。
list.sort(Comparator.naturalOrder()); // 昇順
System.out.println(list.toString());
result:
[1, 2, 3, 4, 5]
Arrays.sort()
同様、第2引数でComparatable を指定する。
Collections.sort(list, Comparator.reverseOrder());
System.out.println(list.toString());
result:
[5, 4, 3, 2, 1]
stream.sorted の場合
StreamAPIでもソートは可能、 stream.sorted()
メソッドを使う。
Streamを多用する場合はこれ知ってるだけで良さげ。 基本ワンライナーで書ける。
stream.sorted の場合(プリミティブ型)
今まで同様、Comparatableを実装していないプリミティブ型の Streamでは、ソートは昇順しかできない。
int array[] = {3, 2, 1, 5, 4};
System.out.println(
Arrays.toString(Arrays.stream(array).sorted().toArray()) // 昇順
);
result:
[1, 2, 3, 4, 5]
参考:http://docs.oracle.com/javase/jp/8/docs/api/java/util/stream/Stream.html#sorted--
stream.sorted の場合(Comparatableを実装した型)
Comparatable を実装した型であれば、 .sorted(Comparator.naturalOrder)
で昇順、降順を指定できる。
Integer array[] = {3, 2, 1, 5, 4};
System.out.println(
Arrays.toString(Arrays.stream(array).sorted(Comparator.naturalOrder()).toArray()) // 昇順
);
result:
[1, 2, 3, 4, 5]
System.out.println(
Arrays.toString(Arrays.stream(array).sorted(Comparator.reverseOrder()).toArray()) // 降順
);
result:
[5, 4, 3, 2, 1]
Comparatable を実装していない独自型の場合
Comparatable を実装していない独自型でも、 Comparatable.comparing()
で指定の値でソートすることできる。
Comparatable を実装していない独自型の場合(配列)
名前String name_
と年齢int age_
のメンバを持った独自クラスPerson を考えた場合、String name_
でのソートや、 int age_
でのソートができる。
Comparator.comparing(Person::getAge)
とすれば、 年齢のソートとなる。
class Person {
private String name_;
private int age_;
public Person(String name, int age) {
this.name_ = name;
this.age_ = age;
}
public String getName() {
return this.name_;
}
public int getAge() {
return this.age_;
}
@Override
public String toString() {
return this.name_ + ", " + this.age_;
}
}
Person people[] = {
new Person("Sato", 20),
new Person("Tanaka", 15),
new Person("Suzuki", 35),
new Person("Yamamoto", 40),
new Person("Koyama", 10)
};
Arrays.sort(people, Comparator.comparing(Person::getAge));
System.out.println(Arrays.toString(people));
result:
[Koyama, 10, Tanaka, 15, Sato, 20, Suzuki, 35, Yamamoto, 40]
降順にしたい場合は、 Comparator.comparing(Person::getAge).reversed()
とすればいい。
Arrays.sort(people, Comparator.comparing(Person::getAge).reversed());
System.out.println(Arrays.toString(people));
result:
[Yamamoto, 40, Suzuki, 35, Sato, 20, Tanaka, 15, Koyama, 10]
Comparatable を実装していない独自型の場合(stream)
Stream でも同様にソートできる。
年齢のソート(昇順):
System.out.println(
Arrays.toString(Arrays.stream(people).sorted(Comparator.comparing(Person::getAge)).toArray())
);
result:
[Koyama, 10, Tanaka, 15, Sato, 20, Suzuki, 35, Yamamoto, 40]
年齢のソート(降順):
System.out.println(
Arrays.toString(Arrays.stream(people).sorted(Comparator.comparing(Person::getAge).reversed()).toArray())
);
result:
[Yamamoto, 40, Suzuki, 35, Sato, 20, Tanaka, 15, Koyama, 10]
名前順(昇順):
System.out.println(
Arrays.toString(Arrays.stream(people).sorted(Comparator.comparing(Person::getName)).toArray())
);
result:
[Koyama, 10, Sato, 20, Suzuki, 35, Tanaka, 15, Yamamoto, 40]
名前順(降順):
System.out.println(
Arrays.toString(Arrays.stream(people).sorted(Comparator.comparing(Person::getName).reversed()).toArray())
);
result:
[Yamamoto, 40, Tanaka, 15, Suzuki, 35, Sato, 20, Koyama, 10]
サンプルコード
参考リンク
-
(o1, o2) -> o1 - o2 なんて呪文はもうやめて! - Java8でのComparatorの使い方 - Qiita
-
http://docs.oracle.com/javase/jp/8/docs/api/java/util/Arrays.html#sort-int:A-
-
http://docs.oracle.com/javase/jp/8/docs/api/java/util/Arrays.html#sort-T:A-java.util.Comparator-
-
http://docs.oracle.com/javase/jp/8/docs/api/java/util/Collections.html#sort-java.util.List-
-
http://docs.oracle.com/javase/jp/8/docs/api/java/util/stream/Stream.html#sorted--