Java初心者の競技プログラミング日記

Dvorak配列でjavaを書いてます

自作クラスの入ったリスト・配列をソートする方法

まずはリスト。

class Point {
	int x;
	int y;
	char color;
	Point(int a, int b, char c) {
		this.x = a;
		this.y = b;
		this.color = c;
	}
	int getX() {
		return this.x;
	}
	int getY() {
		return this.y;
	}
	char getColor() {
		return this.color;
	}
}


クラスPointが入っているリストlistを、それぞれのメンバ変数についてソートしてみる。

//xで昇順ソート
list.sort(Comparator.comparing(Point::getX));

//yで降順ソート
list.sort(Comparator.comparing(Point::getY).reversed());

//colorで昇順ソート
list.sort(Comparator.comparing(Point::getColor));

//xで昇順ソート、xが同じ場合はyで降順ソート、yも同じ場合はcolorで昇順ソート
list.sort(Comparator.comparing(Point::getX)
		.thenComparing(Point::getY).reversed()
		.thenComparing(Point::getColor));


メンバ変数xでソートする場合、xを取得するメソッドがクラス側に必要。

thenComparingで同じ値だった場合のソート条件を追加できる。

また、import static java.util.Comparator.* とインポートすることでComparatorの部分を省略できる。





次に配列。

class Person {
	String name;
	int age;
	Person(String s, int n) {
		this.name = s;
		this.age = n;
	}
	String getName() {
		return this.name;
	}
	int getAge() {
		return this.age;
	}
}


クラスPersonが入っている配列arを、それぞれのメンバ変数についてソートしてみる。

//nameで昇順ソート
Arrays.sort(ar,Comparator.comparing(Person::getName));

//ageで降順ソート
Arrays.sort(ar,Comparator.comparing(Person::getAge).reversed());



追記。以前、文字列の長さでソートする問題があったことを思い出したので、それもやってみる。

List<String> list = new ArrayList<>() と宣言した単純なString型のリストであれば、

・list.sort(Comparator.comparingInt(String::length));

とすることで、文字列の長さが短い順でソートできる。

では、上記のようなPerson型のオブジェクトが入っているリストを、nameの長さでソートする方法は?

少し調べてみたが分からない。Person::getName.length など色々試してみたがダメ。

解決策としては、nameの長さを変数nameLengthに入れておいて、

・list.sort(Comparator.comparing(Person::nameLength));

とすればいいと思う。





以下のサイトを参考にしました
Javaで自作クラスをソートする3通りの方法【Java8】 - 俺とプログラミング
(o1, o2) -> o1 - o2 なんて呪文はもうやめて! - Java8でのComparatorの使い方 - Qiita