雑草SEの備忘録

[旧:東大卒SEの備忘録]東大を卒業し、SEとして働くことになった。備忘録的に作業を綴る。

JavaのComparatorを使って配列を並び替える(課題解答編)

昨日の記事が個人的には気持ちよく書けたので、忘れないうちに課題の回答例を載せておきます。
色々なやり方があると思いますので、試してみてくださいね。

問1.配列studentarrayを身長順に並べよ。

Arrays.sort(studentarray, new Comparator<Student>() {
	public int compare(Student student1, Student student2) {
		return student1.getHeight() - student2.getHeight();
	}
});


問2.配列studentarrayを年齢順に並べよ。年齢が同じ場合は、身長順に並べること。

Arrays.sort(studentarray, new Comparator<Student>() {
	public int compare(Student student1, Student student2) {
		int temp = student1.getAge() - student2.getAge();
		if (temp == 0)
			temp = student1.getHeight() - student2.getHeight();
		return temp;
	}
});


問3.配列studentarrayを名前順に並べよ。名前が同じ場合は、身長順に並べること。

Arrays.sort(studentarray, new Comparator<Student>() {
	public int compare(Student student1, Student student2) {
		int temp = student1.getName().compareTo(student2.getName());
		if (temp == 0)
			temp = student1.getHeight() - student2.getHeight();
		return temp;
	}
});


問4.配列studentarrayのサイズを7にし、以下のを追加する。
   studentarray[6] = new Student("くらもとますみ", 26, 'x', 168)
   この状態で、性別が'x'→'f'→'m'の順にならべよ。同じ性別内では、年齢順に、同じ年齢であれば名前順(あいうえお順)に並べよ。
(解説)
いろいろな実装法があると思いますが、表を使ってまとめる方法を紹介します。
compare()メソッドの引数は、student1とstudent2の二つですが、今回、性別は、f,m,xの3つですので、3^2(3の2乗)で9通りあります。例えば、同じ性別の時は変数tempには0のまま、それ以外の時は、正の値や負の値を与えるような実装をします。今回は、x→f→mの順番に並べたいので、student1の性別がfでstudent2の性別がmのとき、returnで正の値を返すようにします。
(この表の正負を逆にするとm→f→xの順に並びます。ちなみに私は最初逆にしてましたが、実行してみて逆であることに気づきました。)

st1\st2 f m x
f 0 -1 1
m 1 0 1
x -1 -1 0

この6つのif文を抜けてもtempが0のまま(つまり性別が同じ)であれば、年齢で、年齢も同じならば名前で並び替えるようにif文を続けます。

Arrays.sort(studentarray, new Comparator<Student>() {
	public int compare(Student student1, Student student2) {
		int temp = 0;
		// 性別から、順序を定めるために全9通りのうち性別が異なる
		// 6通りから判断し、tempに格納する。同じ性別の場合は0のまま。
		if (student1.getSex() == 'f' && student2.getSex() == 'm')
			temp = -1;
		if (student1.getSex() == 'f' && student2.getSex() == 'x')
			temp = 1;
		if (student1.getSex() == 'm' && student2.getSex() == 'f')
			temp = 1;
		if (student1.getSex() == 'm' && student2.getSex() == 'x')
			temp = 1;
		if (student1.getSex() == 'x' && student2.getSex() == 'f')
			temp = -1;
		if (student1.getSex() == 'x' && student2.getSex() == 'm')
			temp = -1;
		// 同じ姓別である場合は、年齢順に
		if (temp == 0)
			temp = student1.getAge() - student2.getAge();
		// 同じ性別で同じ年齢ならば、名前順に
		if (temp == 0) 
			temp = student1.getName().compareTo(student2.getName());
		return temp;
	}
});

本来ならば、前述の表の様な二次元配列を作成して、fを0、mを1、xを2に読み替えて二次元配列から-1,0,1を取り出す方法がスマートなのかもしれませんが、少しわかりにくく、Comparatorの使い方の説明とは趣旨が離れてしまうので辞めました。

以上、JavaのComparatorの説明でした。お読みいただき、有難うございました。