『Java』List<Object>でソートを実装する。ComparableとComparator

  • Pocket
  • このエントリーをはてなブックマークに追加
  • 172 follow us in feedly

まえがき

今回はJavaでのListで管理しているオブジェクトのソート機能を実装する方法をメモ。

ComparableインターフェースとComparatorインターフェースを用いることでクラス独自のソートを実装できるのだああ

この2つのインターフェースのどっちを選択するかは自由どす。場合によったベストな選択ができるよう両方知っておくためのメモです

Comparableインターフェース

Comparableインターフェースを用いたソートの実装ではそのソート対象のオブジェクトのクラス自身にimplementsして、自身の値と他のオブジェクトとで比較をする。後に紹介するComparatorと違い新しいクラスを作る必要がないのがメリット

今回はArchiveというクラスを用いてサンプルを作成。

yyyy mm の形で年と月の情報を持っているクラスで『yyyy-mm』の順番でソートしたいとうケース

public class Archive implements Comparable<Archive>{

	public String year;
	public String month;
	public int postCount;
	
	public Archive(){
	}
	
	/**
	 * yyyy-mm formated String
	 * @return
	 */
	public String getRequestDate(){
		return year + "-" + month;
	}

	@Override
	public int compareTo(Archive another) {
		return this.getRequestDate().compareTo(another.getRequestDate());
	}

}

implements Comparable すると『public int compareTo(Archive another)』メソッドを実装する必要がある。

この『compareTo』で返すべき返り値としては『-1』『0』『1』のいづれか。

  • 『-1』引数で渡されたオブジェクトより小さい
  • 『0』引数で渡されたオブジェクトと等しい
  • 『1』引数で渡されたオブジェクトより大きい

JavaでのString型の比較には『String.compareTo()』メソッドがあり、こいつの戻り値が『-1』『0』『1』で返ってくるのでそれをそのままリターンするだけで今回のケースは終わり

Rubyでは『<=>』の宇宙演算子を用いてオブジェクトのソートが書けるがそれと同じような感じである。

じっさいにListオブジェクトからソートする際にはこんな感じのコードになる

archives = new ArrayList<Archive>();
.................
Collections.sort(archives);

Comparatorインターフェース

さて続いてはComparatorインターフェースを用いた実装

Comparatorインターフェースを用いた実装では新しくソートルールを定義したクラスを作成して、そのクラスの『compare()』オブジェクトで引数に与えた2つのオブジェクトを比較して、ソートする

今回はTagクラスのソートを行うPostCountComparatorクラスを作成。Tagクラスでは『postCount』という投稿数に関するint型のプロパティを持っていて、この値でソートを行いたい

public class PostCountComparator implements Comparator<Tag>{
	
		public static final int ASC = 1;
		public static final int DESC = -1;
		
		private int sort = DESC;
		
		public PostCountComparator(){
		}
	
		public PostCountComparator(int sort){
			this.sort = sort;
		}
		
		@Override
		public int compare(Tag tag1, Tag tag2) {
			return tag1.postCount > tag2.postCount? 1*this.sort: -1*this.sort;
		}
	}

ConmaratorインタフェースのcompareメソッドもComparableの時と同様に『-1』『0』『1』のいづれかの数値を返すように実装する

  • 『-1』引数1は引数2より小さい
  • 『0』引数で渡されたオブジェクトと等しい
  • 『1』引数1は引数2より大きい

今回は昇順・降順の両方に対応するために『-1』か『1』の値を持つプロパティ『sort』と掛け算した値を返すようにしている。これで降順にソートしたい倍はプラスマイナスがひっくり返った値が返るようになる

実際にListでソートする際にはこんな感じの書き方になる

// 昇順ソート
Collections.sort(tags, new PostCountComparator(PostCountComparator.ASÇ));

// 降順ソート
Collections.sort(tags, new PostCountComparator(PostCountComparator.DESC));

わざわざ新しいクラスファイルを作成したくない場合はインナークラスとしてつかってもいいかもー

おすすめ書籍

増補改訂版Java言語で学ぶデザインパターン入門
結城 浩
ソフトバンククリエイティブ
売り上げランキング: 6,301

関連記事

no image

【DELETE】ActiveObjectsを使ったjavaでのDB接続【その4】

まえがき 久しぶりのActiveObjectsに関する記事です。 ...

記事を読む

images

【Android開発Tips】クリップボードにコピーする機能を実装する

まえがき 今回はAndroid開発でクリップボードに文字列をコピーす...

記事を読む

『Android開発』インテントにオブジェクトを渡す方法をメモ

まえがき Androidアプリで画面遷移の際にインテントを使って、数値...

記事を読む

images

【Android開発Tips】WEBビューを使ってみる

まえがき けっこうお久しぶりのブログです。 それもそのはずで、今週...

記事を読む

junit-tutorial-1junit-tutorial-1.png

EclipseではじめるJUnit、QuickJUnitプラグインのインストールなど

まえがき Java言語のユニットテストのテスティングフレームワークであ...

記事を読む

新着記事

no image

PHPでRubyのirbっぽいインタラクティブなスクリプトが実行できる「boris」

まえがき PHPでもRubyのirbみたいなことがしたくて探してみたと...

記事を読む

2015年の抱負と去年の振り返り〜よちよちWEB業界1年経験して〜

まえがき あけましておめでとうございます。今年もどうぞよろしくお願いし...

記事を読む

Java SE 7 Bronze試験(1Z0-802)を受けてきました

まえがき 以前から少し受けてみたかった試験『Java SE 7 Bro...

記事を読む

HubotでJenkinsのジョブを実行する

まえがき HubotをつかってJenkinsのジョブをじっこうしてみた...

記事を読む

no image

Hubotをforeverでデーモン化する

まえがき 今回はHubotをforeverを使ってデーモン化してみた時...

記事を読む

スポンサーリンク

PAGE TOP ↑