javaを勉強しています。
Collection.sort(); を呼ぶと本の発行日付の古い順に並び替えられるようにcompareTo()メソッドを定義するという問題ですが、解答には
public int compareTo(Book o){ return this.publishDate.compareTo(o.publishDate); }
という解答が載っています。これでなぜ古い順に並ぶのかが理解できません。
この時のthisはどなたなのでしょうか。
o.publishDateが引数のpublishDateだとわかりますが...どのpublishDateと比べているのでしょう。比べる対象一つずつ全てという理解でよいですか?
また、昇順にソートする際にcompareTo()を定義するとき、教科書には口座番号を例にとって
public int compareTo(Account obj){ if(this.number < obj.number){ return -1; } if(this.number > obj.number){ return 1; } return 0; } }
という形が記載されていてそのように覚えたのですが、この形を使ってできないのでしょうか。
そのあたりを解説して頂けたら大変助かります。
よろしくお願い致します。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答2件
0
ベストアンサー
こんにちは。
ご質問にある
この形を使ってできないのでしょうか。
に対しての回答を以下の例(ファイル名:Book.java
)を用いて説明します。
java
1import java.text.DateFormat; 2import java.text.SimpleDateFormat; 3import java.util.Arrays; 4import java.util.Date; 5 6/** 7 * 書籍クラス 8 */ 9public class Book implements Comparable<Book> { 10 11 private String title; // タイトル 12 private Date publishDate; // 発行日 13 private int price; // 価格 14 15 public Book(String title, Date publishDate, int price) { 16 this.title = title; 17 this.publishDate = publishDate; 18 this.price = price; 19 } 20 21 public String toString() { 22 DateFormat df = new SimpleDateFormat("yyyy/MM/dd"); 23 String str = String.format("「%s」(%s) ¥%d", title, df.format(publishDate), price); 24 return(str); 25 } 26 27 public int compareTo(Book other) { 28 return(this.publishDate.compareTo(other.publishDate)); 29 } 30 31 public static void main(String[] args) throws Exception { 32 33 DateFormat df = new SimpleDateFormat("yyyy/MM/dd"); 34 35 // Book の配列を作成 36 Book[] myBooks = new Book[]{ 37 new Book("EFFECTIVE JAVA 第2版", df.parse("2014/3/11"), 3888), 38 new Book("Pythonではじめる機械学習", df.parse("2017/5/25"), 3672), 39 new Book("JavaScript Ninjaの極意", df.parse("2013/5/25"), 3672), 40 new Book("Rubyによるクローラー開発技法", df.parse("2014/8/23"), 3218) 41 }; 42 43 // ソートする 44 Arrays.sort(myBooks); 45 46 // 配列の要素を順に表示 47 for (Book b: myBooks) { 48 System.out.println(b); 49 } 50 } 51} 52
上記をコンパイル、実行すると、myBooks
がpublishDate
(発行日付)の昇順に以下が出力されます。
「JavaScript Ninjaの極意」(2013/05/25) ¥3672
「EFFECTIVE JAVA 第2版」(2014/03/11) ¥3888
「Rubyによるクローラー開発技法」(2014/08/23) ¥3218
「Pythonではじめる機械学習」(2017/05/25) ¥3672
上記のコードで、Book
クラス の compareTo
メソッドでは、
java
1 public int compareTo(Book other) { 2 return(this.publishDate.compareTo(other.publishDate)); 3 }
としており、ご質問にあるコードと同じように、Date
型の compareTo
メソッドを
使っています。
上記のコードを例に使いますが、以下のご質問
・・・という形が記載されていてそのように覚えたのですが、この形を使ってできないのでしょうか。
に対しては、できます が答えです。
この形
に似せて書くと、Book
の compareTo
メソッドは例えば以下のようなものになるでしょう。
java
1 public int compareTo(Book other) { 2 3 long thisTime = this.publishDate.getTime(); 4 long otherTime = other.publishDate.getTime(); 5 6 if (thisTime < otherTime) 7 return -1; 8 else if (thisTime > otherTime) 9 return 1; 10 else 11 return 0; 12 }
上記で、Date
型の getTime()
メソッドを使っていますが、
これは Date
オブジェクトが示す日時の、1970年1月1日 00:00:00 GMTからの
経過時間をミリ秒で返します。
試しに、冒頭に挙げた Book.java
の compareTo
を上記のように
変えて実行してみてください。同じく、日付の昇順に表示されると思います。
補足ですが、
この時のthisはどなたなのでしょうか。
とあるのですが、this
の理解が曖昧であることと、 Comparable
インターフェースの
compareTo
メソッドの実装の仕方が分からないということとは別の問題で、
前者のほうがより基礎に近い話なので、Comparable
やソートといったテーマから
切り離した、よりシンプルなコードで、ご自身の this
に
ついての理解について確認する、新たな質問をされたほうがよろしいかと思います。
以上参考になれば幸いです。
投稿2018/01/21 06:37
編集2018/01/21 07:52総合スコア9058
0
Bookクラスで宣言しているフィールドのpublishDateが何型なのか記載されていませんが(おそらくjava.util.Date型かjava.time.LocalDate型だろうと思われますが)、そのコードが正常に機能するのであれば、publishDate型のクラスがComparableインターフェイスを正しく実装しているということです。
APIドキュメントで確認してみてください。
またそのコードの「this」が何を表しているのかわからないとのことですが、Javaでは常にthisが表すのは自身のインスタンスです。つまり提示の例ではおそらくBookクラスの中にそのcompareToメソッドが書かれていると思いますが、そのBookクラスのインスタンスがthisの参照先となります。したがってコードの解釈としては自分自身(Bookインスタンス)が持つpublishDateフィールドの値と、compareToメソッドが受け取った別のBookインスタンスが持つpublishDateのフィールドを比べて結果を返しているということです。
ちなみに「Collection.sort()」ではなく「Collections.sort()」ですよね?
CollectionsクラスのsortメソッドはAPIドキュメントにあるようにComparableインターフェイスを実装しているオブジェクトを並べ替えますが、その際、sortメソッドの内部では先ほどのcompareToメソッドを呼び出して並べ替えの処理を行っています。
口座番号の例が載っていますが、そのフィールドnumberの型はおそらくint型だと思われ、基本データ型のままではcompareToメソッドを呼び出すことができないためそのようなコードになっています。int型ではなくInteger型であれば、Date型やLocalDate型と同じようにcompareToメソッドが実装されているため、this.number.compareTo(obj.number)というコードを書くことができます。
また、もちろんpublishDateの比較を自前でそのように実装することも可能ですが、すでに実装されているcompareToメソッドが利用できるのであれば、利用することが推奨されます。
投稿2018/01/21 04:38
総合スコア402
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/01/21 07:35
2018/01/21 07:53
2018/01/21 07:57
2018/01/21 15:14
2018/01/21 15:20