🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

1回答

1414閲覧

Comparatorインターフェースは関数型インターフェース?

yusei_039

総合スコア6

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

1クリップ

投稿2021/03/18 16:18

現在、川場隆さんの『新 わかりやすいJava オブジェクト指向 徹底解説』という本を読んで勉強しています。

このテキストでは、Comparatorインターフェースはcompareメソッドだけをもつ関数型インターフェースである、と書かれていました。

しかしjavaのAPIを参照してみるとComparatorインターフェースにはcompareメソッドだけでなく、equals()という抽象メソッドもありました。抽象メソッドが二つあるのに関数型インターフェースと呼ばれるのはなぜだろうと自分なりに考えたので、次の考えが正しいのかどうか判断していただけないでしょうか。


1.Comparatorインターフェースの抽象メソッドは一つか、二つか?

Comparatorインターフェースを実装したクラスは、必ずObjectクラスを継承してるはずなのでequalsメソッドは既に具象メソッドとして存在する。従ってComparatorインターフェースの実装においてはequalsメソッドをオーバーライドする必要はなく、compareメソッドだけをオーバーライドすれば良い。
つまり、Comparatorインターフェースの本質的な抽象メソッド(オーバーライドが必ず要求されるメソッド)は実質compareメソッドの一つしかない。
よってComparatorインターフェースの(本質的な)抽象メソッドは一つであるため、関数型インターフェースである。

2.なぜ不必要に思える抽象メソッドequals()をComparatorインターフェース内に書いたのか?

上記の考え方であれば、Comparatorインターフェースの中にequalsメソッドを抽象メソッドとして書いておく必要がありません。なぜこんなものを書いておいたのか疑問に思っていましたが、ComparatorインターフェースのequalsメソッドのAPIをみたところ次のような説明文がありました。

Indicates whether some other object is "equal to" this comparator. This method must obey the general contract of Object.equals(Object). Additionally, this method can return true only if the specified object is also a comparator and it imposes the same ordering as this comparator. Thus, comp1.equals(comp2) implies that sgn(comp1.compare(o1, o2))==sgn(comp2.compare(o1, o2)) for every object reference o1 and o2.

つまり、Comparatorインターフェースを実装したクラスのインスタンスの等価性は、上述のほげほげの時に限りtrueを返しなさいと言っています。確かに、この説明文がないとうっかり変なオーバーライドをしてしまうかもしれません。
すなわち、この説明文をAPIに書くためだけにわざわざ不必要に見えるequals()をComparatorインターフェースの中に書いていた(と予想しています)。

※またこの後の説明文に、equals()をこのようにオーバーライドしておけばパフォーマンスが向上することもあるよ、と書かれていました。equals()のオーバーライドはあくまでも必須ではない点が、実装先のクラスでわざわざオーバーライドをせずともエラーにならない点と合致していて、自分の中ではより納得しています。


一応、APIの参照を載せておきます。
ComparatorインターフェースのAPI

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

抽象メソッドが二つあるのに関数型インターフェースと呼ばれるのはなぜだろうと自分なりに考えた

自分なりに考えることはありません。
言語仕様の定義を確認しましょう。

https://docs.oracle.com/javase/specs/jls/se16/html/jls-9.html#jls-9.8-120

The definition of functional interface excludes methods in an interface that are also public methods in Object.

関数型インターフェイスの定義では、Objectのpublicメソッドでもあるインターフェイスのメソッドは除外されます。

と明記されています。

投稿2021/03/19 01:58

quickquip

総合スコア11231

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yusei_039

2021/03/19 02:55

ありがとうございます。定義はわかりました。
quickquip

2021/03/19 02:59

2. は同感で"docstring に説明を書くこと"の方が目的なように思います。
yusei_039

2021/03/19 03:03

ありがとうございます。おかげで霧が晴れました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問