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

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

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

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

インターフェース

インターフェイスという用語はハードウェア・ソフトウェアの両方に使うことができます。 一般的に、インターフェイスは内部処理の詳細を見せないように設定されます。オブジェクト指向プログラミングにおいて、インターフェイスはabstractクラスとして定義されます。

Q&A

解決済

3回答

4011閲覧

Comparableを実装しようとして出る警告の原因

throwsNullPo

総合スコア17

Java

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

インターフェース

インターフェイスという用語はハードウェア・ソフトウェアの両方に使うことができます。 一般的に、インターフェイスは内部処理の詳細を見せないように設定されます。オブジェクト指向プログラミングにおいて、インターフェイスはabstractクラスとして定義されます。

0グッド

1クリップ

投稿2015/12/19 18:04

プログラミング初心者です。
Carクラスを
●フィールドとして4桁のナンバーと倍精度のガソリン量を持つ
●Comparableインターフェースを実装する(compareTo()を必ずオーバーライドしなければいけないものと認識しています)
●Collections.sort()を使って定義したメソッドでList<Car>を代入した時にListの中身を4桁のナンバーの昇順で並べ替える

の三点を満たすように作りたいと考えています。以下のようにすると一応それっぽく動くのですがCarクラスだけ単独でコンパイルすると警告メッセージが出てきてしまいます。この警告は問題ないものなのかあるいは下記のコードが推奨されない(またはやってはいけない)書き方を含んでいるのか教えていただけるでしょうか。


import java.util.;
import java.lang.
;
import java.io.*;

public class Car implements Comparable{
private int iNum;
private double dGas;

public Car(int iNum, double dGas){ this.iNum = iNum; //車のナンバー this.dGas = dGas; //車のガソリン残量 } public int getNum(){ return this.iNum; } public double getGas(){ return this.dGas; } @Override public int compareTo(Object obj){ if(obj instanceof Car){ Car car = (Car) obj; if(this.getNum() > car.getNum()){ return 1; }else if(this.getNum() < car.getNum()){ return -1; }else{ //等号成立の時 return 0; } }else{ ClassCastException e = new ClassCastException(); throw e; } } @Override public String toString(){ return "number:" + this.iNum + "\tgas:" + this.dGas; } public static void SortCar(List<Car> cars){ Collections.sort(cars); }

}


import java.io.;
import java.util.
;
import java.lang.*;

class CarTest{
public static void main(String[] args){
Car car0 = new Car(1003, 10.0);
Car car1 = new Car(1002, 10.0);
Car car2 = new Car(1001, 10.0);
Car car3 = new Car(1000, 10.0);

List<Car> cars = new ArrayList<Car>(); cars.add(car0); cars.add(car1); cars.add(car2); cars.add(car3); System.out.println("*****並べ替え実行前*****"); System.out.println(cars.get(0)); System.out.println(cars.get(1)); System.out.println(cars.get(2)); System.out.println(cars.get(3)); Car.SortCar(cars); System.out.println("*****並べ替え実行後*****"); System.out.println(cars.get(0)); System.out.println(cars.get(1)); System.out.println(cars.get(2)); System.out.println(cars.get(3)); }

}

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

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

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

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

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

guest

回答3

0

ベストアンサー

ほかの方が回答している通り、Comparableは「なんのクラス型と比較できるか」を宣言するジェネリクスがあります。ここでComparable<Car>と宣言すれば、compareToメソッドが

java

1public int compateTo(Car another){ 2 .... 3}

のように、Car型(か、そのサブクラス)だけを受け付けるようになります。現時点ではその比較対象になるべき型が不明瞭のため、警告を発していると思われます。

わざわざinstanceofでチェックしているのに、falseの時にClassCastExceptionを発生させるなら場合分けしている意味がありません。
また、このメソッドで返すint値は、「正か負か、あるいはゼロか」が重要でその絶対値に意味はないので、

java

1public int compateTo(Car another){ 2 return this.getNum() - another.getNum(); 3}

でも十分です(ただし0とInteger.MIN_VALUEとの比較でこれを使うと不整合を起こすので注意)。
あるいは、Integerクラスに2つのint値を比較するstaticメソッドも存在するので、

java

1public int compateTo(Car another){ 2 return Integer.compare(this.getNum(), another.getNum()); 3}

という書き方も可能です。

投稿2015/12/19 23:55

編集2015/12/21 14:40
swordone

総合スコア20649

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

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

throwsNullPo

2015/12/20 19:38

皆さま ご指摘いただいたジェネリック型の扱いに注意したところ警告の出ないものに仕上がりました。重ねてお礼申し上げます。
guest

0

コードを見る限り、クラス定義の Comparable で比較対象とするクラス型が省略されており、これが原因だと推測しますが、開発環境の警告レベルの設定で、警告の内容や数は変わりますので、具体的な警告メッセージも併せて書くようにする方がよいかもしれません。

compareTo() メソッドの実装において public int compareTo(Object obj) と定義していますので、これに沿う形にするのであれば、クラス定義は public class Car implements Comparable<Object> にすると警告が出なくなるのではないでしょうか?

ただし、上記は警告を黙らせるための手直しであり、本来のゴールであるかどうかはわかりません。Comparable<Object> を使うよりも Comparable<Car> とするなど、比較対象の範囲によって書き方が変わってきますので、この部分を深く知りたければ(初心者であれば難しいかもしれませんが)JDK1.5 で追加された総称型(ジェネリクス)を紐解くと良いでしょう。


今回のパターンの警告は自分で使うだけであれば問題ないかもしれませんが、無茶すると危ない使い方もされうるので、意図している適切な形で実装したほうがよいと思います。

基本的に警告は無視すると危ないかもしれないけれど動くよ。というものですから、ある意味、開発者に委ねられる内容です。厳密なモノを作りたいのであれば、警告に対して原因から適切な対処を行う事が望ましいですし、自身が問題ないと判断できる警告内容は当然無視しても構いません。ただし『警告が出た場合は考えなしに黙らせる』というのは非常に危険な行為ですので、すべきではありません。理解して意図を持ったコードを書くようにすると良いでしょう。

投稿2015/12/19 19:52

ps13zier

総合スコア433

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

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

0

たぶん、ジェネリックの警告ですね。

<<追記>>
イメージ説明

警告を取る書き方は以下のようにジェネリックタイプを指定することです。
イメージ説明

List list = new ArrayList();
が曖昧な表現だから改めた方がいいですよ、っていう警告。
これをなくすには、
List<Car> list = new ArrayList<Car>();
とするか、
List<Car> list = new ArrayList<>();
こうします。
ArrayList<>() でも、ArrayList<Car>() でも警告なしにコンパイルが通ります。
前者は、Java1.7 までの構文、java1.8 からは、左辺の generic 型が指定されていれば
右辺はコンパイラが<> に入る型を推論してくれるのでこの記述が可能になっています。

以上です。

投稿2015/12/19 18:53

編集2015/12/20 04:35
ipadcaron

総合スコア1693

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

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

throwsNullPo

2015/12/19 19:40

回答ありがとうございます。 エディタ:秀丸 コンパイラ:最新版 でコマンドプロンプトから実行しています。パッケージの概念を理解するのにちょうどよかったので自主的に今の環境でやっています。(今でも時々コンパイルの仕方を間違えるのでもう少しなれてからeclipseに移行しようかと思っています。実は始めたばかりのころにeclipseを触ってみたのですが当時は複雑すぎてあまりありがたみが実感できませんでした。) ちなみに独学です。実際には商品が数万個あって、価格順、商品コード順、日付順それぞれでソートできるようなものを作ろうとしています。
swordone

2015/12/20 08:19

ソート項目が複数あるようなら、Comparableを対象のクラスに実装するのではなく、 対象のクラスとは別にComparatorの実装クラスを複数作って使い分けるというほうが適していると思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問