質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.48%
Java

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

Q&A

解決済

3回答

5456閲覧

Comparatorの<? super T>の意味

jaguarundi

総合スコア19

Java

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

0グッド

0クリップ

投稿2019/01/10 02:39

前提・実現したいこと

Javaで木構造の勉強をしております。
Javaについてはジェネリクス型まで一通りさらってからデータ構造を勉強しているのですが、
教科書に唐突に出てきた<? super T>の意味がわからず困惑しております。

該当のソースコード

Java

1private Node<K, V> root; // 根 2 private Comparator<? super K> comparator = null; // コンパレータ 3 4 // --- コンストラクタ ---// 5 public BinTree() { 6 root = null; 7 } 8 9 // --- コンストラクタ ---// 10 public BinTree(Comparator<? super K> c) { 11 this(); 12 comparator = c; 13 }private Node<K, V> root; // 根 14 private Comparator<? super K> comparator = null; // コンパレータ 15 16 // --- コンストラクタ ---// 17 public BinTree() { 18 root = null; 19 } 20 21 // --- コンストラクタ ---// 22 public BinTree(Comparator<? super K> c) { 23 this(); 24 comparator = c; 25 }

試したこと

非境界ワイルドカード型という総称?のようですが、一時間ほど格闘してもあまり実態がつかめませんでした(superがついているのでより複雑?)

非境界ワイルドカード型について、そもそも一般的に使われているのかなど、初心者にわかりやすく教えていただけないでしょうか。

よろしくお願いいたします。

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

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

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

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

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

guest

回答3

0

? super Kは「下限境界ワイルドカード」です。
「非境界ワイルドカード」は?単体の時に言い、? extends Tという形の「上限境界ワイルドカード」も存在します。
いずれもJDKのメソッドには結構入っています。Streamクラスを見るとこの表記が多数みられると思います。
簡単に言うと、そのジェネリクスとして受け入れられる型に制限を加える機能です。
この場合Kはこれが属するクラスのインスタンス化の時に決定しますが、これが持つComparatorのジェネリクスはKまたはその親クラス・親インターフェースの型のみ可能という意味になります。

例えばこのNodeクラスをNode<Integer, String>のような型にしたとします。
この時Comparatorは、Integerを比較できるものであればいいことになります。
そのためには、Comparatorのメソッドcompareが、引数にIntegerをとれる形であればいいことになります。
Integer型のオブジェクトは、親クラスであるNumber型の変数にも代入できますし、Object型の変数にも代入できます。
ならば、Comparatorの型はIntegerに限らずとも、Integerの親クラスを扱うものでも問題ないはずです。

java

1// Comparatorのイメージ 2 3// Comparator<Integer> 4public int compare(Integer o1, Integer o2) //これはもちろんIntegerを受けることができる 5 6// Comparator<Number> 7public int compare(Number o1, Number o2) //これでもIntegerを受け取れる 8 9// Comparator<Object> 10public int compare(Object o1, Object o2) //これでも問題なくIntegerを受けられる

そのため、このようなComparatorをすべて使えるようにしたい。また、それ以外のComparator,例えばComparator<String>はIntegerを比較するためには使えないので、それは受けられないようにしたい。
そのような型宣言が、Comparator<? super Integer>なのです。

このページも参考にしてみてください。

投稿2019/01/10 03:02

swordone

総合スコア20651

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

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

0

ベストアンサー

Comparator<? super K>を日本語に直すと、「Kもしくはその先祖クラス(親クラス、その親クラス、...、Object)に対するComparator」となります。

仮に、KIntegerだとしてみましょう。これを比較するには、Comparator<Integer>でももちろん構わないのですが、Comparator<Number>でも比較可能です。意味があるかどうかはともかく、Comparator<Object>を使うことも可能です。このような複数のジェネリック型をまとめて含むのが、Comparator<? super K>です。

非境界ワイルドカード型について、そもそも一般的に使われているのかなど、初心者にわかりやすく教えていただけないでしょうか。

作る側はともかく、使う側としてはよく遭遇するかと思います。正しく作られていれば、変に意識する必要がなく適切な型のものを渡せます。

投稿2019/01/10 02:50

maisumakun

総合スコア145183

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

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

jaguarundi

2019/01/10 03:00

迅速な回答、大変ありがとうございました! 自分の知っているJavaの世界の狭さを再認識しました。 どうやら下限境界ワイルドカード型が正しいようです。 質問に不備があり申し訳ないです・・・
guest

0

説明は回答があるのでワード的観点を。

非境界ワイルドカード型という総称

非境界ワイルドカード型は?のみで表現します。
つまりはどんな型でもOKですよという一見便利そうだけどバグを生みやすいやつです。

質問にある? super Tは下限境界ワイルドカード型といいます。
似たようなもので? extends Tという上限境界ワイルドカード型というのもあります。

ワードを混同してしまうと調べる際にうまくヒットしないので気をつけてくださいね。

投稿2019/01/10 03:02

dice142

総合スコア5158

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問