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

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

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

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

Q&A

解決済

5回答

19887閲覧

等値と等価のちがいについて

k499778

総合スコア599

Java

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

1グッド

1クリップ

投稿2015/09/09 07:25

編集2015/09/10 00:14

Javaで開発をしています。
等値と等価の違いについて知りたいと思っています。

等値=同一
等価=同値

ということなのかなあと思っているのですが、合っているでしょうか?

そもそも

同一は、インスタンスが同じこと。==演算子で判定する。
同値とは、インスタンスは違うけれど、値が同じこと。equalsメソッドで判定する。

だと思っています。

調べてみたのですが、個人的な意見を述べているサイトが多く、いまいち自信が持てません。
字面的には組み合わせも逆のような気がするし、調べていくうちにまったくの別物のような気もしてきました。。

有識者の方々よろしくお願いします。


追記
このサイトを拝見しました。
http://ryo021021.hatenablog.com/entry/2014/01/02/134232

変数で考えます。等値はそのまま、その変数が持っている値が等しいことです。つまり、以下の式です。[==]を"等価演算子"なんて呼ぶために混乱します。

if (a == b) printf("等値\n");

等価は、昇順にソートする場合等でいう以下の式です。

if (!(a < b) && !(b < a)) printf("等価\n");

値を、それ自体で比較するのか、論理的に比較するのか、といった感じでしょうか。

私の認識は違っていたかもしれません。

等価の「論理的に比較する」の意味がいまいちよくわかりません。
もしアドバイスいただける方がいらっしゃればお願いします。

退会済みユーザー👍を押しています

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

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

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

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

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

guest

回答5

0

・等値判定(==)はメモリ内の値が等しいかを判断します。
・等価判定(Object#equals)はインスタンスが等しいかを判定します。

int型はプリミティブなのでObjectを継承していません。そのため、メモリ上の値を等しいかどうかに使います。

対してオブジェクトは内部にたくさんの属性を持っています。そのため、Object型を継承しているクラスはインスタンスの比較基準(どの属性が一致していたら同じかなど)をObject#equalsをオーバーライドして決定することが義務付けられています。
オブジェクトが等価かどうかをオブジェクトの特性などから論理的に判断する行為を「論理的に比較する」と表現しているのではないでしょうか。

投稿2015/09/09 07:59

編集2015/09/09 08:02
yona

総合スコア18155

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

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

k499778

2015/09/09 08:09 編集

yonaさん 回答ありがとうございます。 ということは私の最初の認識で合っていたということでいいのでしょうか? 等値=同一 等価=同値 という認識で。
yona

2015/09/09 08:26

問題ないと思います。理解されていると思いますが、少し補足します。 Hoge a = new Hoge(); Hoge b = new Hoge(); int c = 0; c == 0はイメージのとおり、cは0なのかを判定します、しかしa == bではaとbの参照先は同じかを同値判定しています。そのため、a == bは成り立ちません。しかし、同じコンストラクタを使っており、特に操作していないためa.equals(b)は成り立ちます。 次はb = aをするとbの参照先はaと同じところをさすため、a == bが成り立つようになります。 言葉についてですが ・等値:値が同じかどうかだけで判定する。 ・等価:複数の等値判定をまとめて一つの評価をだすこと。
k499778

2015/09/10 00:54 編集

yonaさん 回答ありがとうございます。 疑問点が3つあります。 ・a.equals(b)が成り立つという点。 ・a==bが同値判定という点。 ・等値と等価の意味。 1点目ですが、 実際試してみて、a.equals(b)が成り立ちませんでした。 私自身もString型をequalsメソッドで比較するけど、オブジェクトをequalsメソッドで比較しないので不思議な感じがしました。 このyonaさんの解釈は合っているのでしょうか? 次のコードで試しました。結果はfalseが返ってきました。 public class Main { public static void main(String[] args) { Hoge a = new Hoge(); Hoge b = new Hoge(); int c = 0; if (a.equals(b)) { System.out.println("true"); }else{ System.out.println("false"); } } } class Hoge { } 2点目ですが、 ==演算子なので、同値ではなくて同一の判定になると思います。 3点目ですが、 私は、逆だと思っていました。 等値=同一(複数の値判定をまとめて一つの評価をだすこと。)、 等価=同値(値が同じかどうかだけで判断する) と前回のコメントでは書かせて頂いたのですが、それは逆ということでしょうか? また http://ryo021021.hatenablog.com/entry/2014/01/02/134232 だと==演算子で比較しているのでyonaさんのおっしゃる等値が同値と同じ意味だと一概に言えない気もしてきたのですが。 僭越ながら、意見を述べさせて頂きました。 思い違いかもしれませんが、このように思った次第であります。
swordone

2015/09/10 00:50

equalsは,デフォルトでは==で比較するのと全く同じ効果となります. 適切に比較するためには,当該クラスでequalsをオーバーライドして適切な比較処理を記述する必要があります.
k499778

2015/09/10 01:10

swordoneさん 回答ありがとうございます。 そうなんですね。勉強になります。 確かに自分なりに解釈してequalsメソッドを該当クラスでオーバーライドし、使ったところa.equals(b)が成り立ちました。trueが返ってきました。 実際に試したのは以下です。 public class Main { public static void main(String[] args) { Hoge a = new Hoge(); Hoge b = new Hoge(); int c = 0; if (a.equals(b)) { System.out.println("true"); } else { System.out.println("false"); } } } class Hoge { private int num; public int getNum() { return num; } public void setNum(int num) { this.num = num; } public boolean equals(Hoge obj) { if (obj == null) { return false; } return this.num == obj.num; } } yonaさん、swordoneさん、勉強になりました。ありがとうございます。 等値と等価は英語を訳した言葉なので、同値・同一に当て込むのは難しそうですね。。
yona

2015/09/10 03:12 編集

ベストアンサーが決まっていますが… >・等値と等価の意味 どうあっても齟齬が出るので 等値と等価という言葉に固執せずに比較演算子==と比較メソッドequals()として理解することが重要です。 >・a.equals(b)が成り立つという点。 swordoneさんの記載通りです。 勝手な思い込みにより混乱させてしまいました。 >・a==bが同値判定という点 プリミティブとインスタンスでは動作が異なります。 プリミティブは値が等しいかの同値判定を行う。 インスタンスでは参照値が等しいかを判定しています。 なので両方とも同値判定をしていることになります。
guest

0

ベストアンサー

間違っていないか不安ですが、自分なりの考えで回答してみます。

例えば、二人の人物を比較するとします。

これを人間(=Humanクラス)として比較するならば、(哲学的には諸説ありそうですが)その「価値が等しい」ことの定義は「全く同じ人物である」ことに他なりません。つまり、Humanクラスにおいて等価の意味は「等値であること」になります。

java

1class Human { 2 public boolean equals(Object obj) { 3 return this == obj; 4 } 5}

走者(=Runnerクラス)として比較するならば、その「価値が等しい」ことの定義は走る速さとスタミナで決まるかもしれません。加えて言えば、相手も走者である必要があります。

java

1class Runner extends Human { 2 protected int speed; 3 protected int stamina; 4 public boolean equals(Object obj) { 5 if (obj instanceof Runner) { 6 runner = (Runner)obj; 7 return this.speed == runner.speed && this.stamina == runner.stamina; 8 } else { 9 return false; 10 } 11 } 12}

短距離走者(=Sprinterクラス)として比較するならばもはやスタミナは問題にならず、その価値はスピードだけで決まるかもしれませんね。比較自体は走者であればだれとでも出来そうです。

java

1class Sprinter extends Runner { 2 public boolean equals(Object obj) { 3 if (obj instanceof Runner) { 4 runner = (Runner)obj; 5 return this.speed == runner.speed; 6 } else { 7 return false; 8 } 9 } 10}

このように二つの物の価値を比べる時に、その評価基準は「それが何であるか」によって変わります。一方で「等しい値である」ことの定義はいつでも同じです。
等値と等価の違いはそこにあるのではないでしょうか。

投稿2015/09/10 01:24

hy3

総合スコア594

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

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

k499778

2015/09/10 02:15

hy3さん 回答ありがとうございます。 丁寧で具体的な説明感謝の限りです。 この考えでいくと、 同じスピードでスタミナが違うランナーとスプリンターをスプリンター目線で比較した場合、 等価ではあるけれど(スプリンターはスピードを評価基準とするため)、 等値ではない(スタミナは同じ値ではないから)。 と考えていいのでしょうか? 等価でクラスを比較する場合、そのクラスによって比較する値が変わる。 等値でクラスを比較する場合、値そのものを比較するためクラスによって比較する値が変わらない。 という認識で。
hy3

2015/09/10 02:31 編集

Javaのクラスは参照型なので、メンバが全て同じ値だからと言って等値とは言えません。 例えば(微妙な例えですが)私がスピード・スタミナどころか体細胞一つ一つまでk499778さんと同じクローン人間だったとしても、別の個体である時点で(等価ではあるかもしれませんが)等値ではありません。 k499778さんと等値なのは、他ならぬk499778さん自身だけである訳です。
k499778

2015/09/10 02:30

そもそも等価・等値という言葉がプログラミング用語というより国語的な意味合いの方が強く、なんだか概念的な説明になってしまいますね。 プログラマーの力量を見極める--面接官になったら尋ねるべき質問実例集 http://japan.zdnet.com/sp/10things/20409456/ の「等値」と「等価」の違いを説明してください。」 の回答を考えていたのですが、日本語で考えるよりpikovoltさんの言っていたとおり英語で考えた方がいいかもしれません。 こんな記事があり http://www.kijineko.co.jp/node/720 「equality」と「equivalence」とで考えています。 これだとある程度プログラミングの中で定義があり、きっちりとした回答ができるのかもしれません。それが 「値を、それ自体で比較するのか、論理的に比較するのか」といった解釈に繋がる気がします。 この質問をプログラミング用語で定義されていない言葉で解釈し、 それを面接官に質問されたら、正直どう答えていいのかと思いました。 hy3さんが答えて下さった「評価基準が異なる」といったニュアンスで伝えればいいのか。 それとも同値、同一のニュアンスで聞いてきているのか。 少し質問としてナンセンスなのかなとも思ってしまいます。 半分個人的感想になってしまいましたが、hy3さんの説明わかりやすかったです。 同値と同一と一緒かどうかではなく、 等値・等価はhy3さんがおっしゃた概念的なところと、 値を、それ自体で比較するのか、論理的に比較するのか、といったところが特徴としてあると理解したいと思います。 ありがとうございました。
hy3

2015/09/10 02:39 編集

私も同意見で、(テーマとして面白くはありますが)ナンセンスだと思っています。 特にプログラム周りの日本語はpikovoltさんが指摘しているように殆どが訳語で、元のニュアンスが正確に伝わらず、正しく使い分けられていないケースが多いのが現実です。 自分自身は出来るだけ正確でいたいとは思いますが、単語だけを取り上げて議論をするのはただの言葉遊びに過ぎず、あまり意味があるものとは思えません。 私が面接を受けるならば、回答する前にその定義をより正確に聞き返します。例えば等値が「==比較結果がtrueであること」、等価が「equalsメソッドでの比較結果がtrueであること」とはっきりさせた上でならば、今回のような回答を返していけるかと思います。
k499778

2015/09/10 02:42 編集

hy3さん さようでございますね。 とりあえず概念的なニュアンスとして 等価:「それが何であるか」によって評価基準が変わるもの。 等値:「それが何であるか」によって評価基準が変わらないもの。 という認識でいきたいと思います。
k499778

2015/09/10 02:52

hy3さん 回答ありがとうございます。 タイムラグでコメントの回答がひとつずつズレています。 申し訳ございません。 そうですよね。 なんだか訳語によるミスリードが大きく、回答者によって思い浮かべることが変わりそうな質問な気がします。 たしかに面談のときは聞き返すようにするといいかもしれませんね。 少しすっきりしました。 ありがとうございました。
hy3

2015/09/10 03:07

なるほど、元記事が英語なのですね。 その日本語訳だけを読んでいるから、なんだかナンセンスな内容が多く見えてしまうのかもしれませんね。 ありがとうございます。
guest

0

たとえば次の値の比較をどう言うか。

java

1int i = 1; 2double d = 1.0;

ここで、 i と d は「等値ではない」が、「等価である」と言いたい。
両者を == で比較してみる。

java

1System.out.println( i == d ); // true

true が返る。

これはあたりまえではない。
いわゆる暗黙の型変換というやつで、int 型 の i を「等価な」 double 値に変換した上で d との等値性を評価している。

では次はどうか。

java

1float f = 0.1f; 2double d2 = 0.1; 3System.out.println( f == d2 ); // false

これも、f と d は等値ではないが、等価であると言いたい。

しかし結果は false になる。
f も「等価な」 double に暗黙的に変換されるが、その結果は等値にならない。

Java の == 演算子はあくまで値のメモリ(やレジスタ)上のビットパターンが完全に一致することを判定する。
これをここではとりあえず等値と呼ぶことにしたい。
暗黙の型変換はそれとは別の話で、コンパイラが空気を読んでサービスでやってくれていることなので、納得いかなくても文句は言えない。

java

1System.out.println( f == (float)d2 ); // true 2System.out.println( 1 == (int)1.99999 ); // true 3System.out.println( 1 == '1' ); // false 4System.out.println( 49 == '1' ); // true 5

1 と 1.0 が等しくあってほしいのは、人間の頭の中であって、コンパイラはできるだけそれに沿った評価をするよう実装されている。
そうすると、もう一方の「等価である」とは何と何を「等しいとみなすか」という、仕様(決め)の問題であるということになる。

オブジェクトのequals()でもう少し考えてみよう。

Java API のドキュメントをみると Object#equals() をみると、equivalence と「同値」、 equal を「等価な」と訳していて微妙だ。

java

1System.out.println( "java" == "JAVA" ); // false 2System.out.println( "java" == "java" ); // true 3System.out.println( "java" == new String("java") ); // false 4System.out.println( "java".equals(new String("java")) ); // true 5System.out.println( "java".equalsIgnoreCase("JAVA") ); // true 6 7ArrayList<String> al = new ArrayList<>(Arrays.asList("a", "b", "c")); 8LinkedList<String> ll = new LinkedList<>(al); 9LinkedHashSet<String> set = new LinkedHashSet<>(ll); 10System.out.println( al.equals(ll) ); // true 11System.out.println( al.equals(set) ); // false

Java の場合 オブジェクトを == で比較するとき、参照値(アドレス)の等値性を見ているのであって、それは「同一」インスタンスかどうかを判定しているにすぎない。オブジェクトについて等値か等価かという区別とは別の話だ。

オブジェクトが等値であるとは、そのメンバとさらにそのメンバを全てたどって、最末端のプリミティブ型データを == で比較して全て一致した場合の事を言うのだろう。しかしそれは現実的ではない。

かと言って、どこで妥協すればいいのか、オブジェクトが等しいかどうかの定義は一概には決められない。 Java ではその判定基準はクラスの equals() 実装に任される。
つまり、Java の equals() は常に等価性で評価するとみなされる。
オブジェクトの内実データが全く異なっていても、あるいはクラス(型)が異なっていても equals() が true を返せばそれらは区別されない。

これが自分なりの理解だけれども、あえて前のコメントの定義に合わせて、「等値」は内部表現(値)の比較であり、「等価」はルール(論理)による比較といってみても、あながちずれてはいないかもしれない。

JavaScript, Ruby, PHP など一部の言語は等値と等価を区別した比較演算子を持っているが、呼び名は一致しない。
C++ は演算子そのものをオーバーライドできて、== でさえプログラマが再定義できるので、等値性は保証されない。

JavaScript

11 == "1"; // true 21 === "1"; // false

言語以外にも、
Windows のファイル名は大文字と小文字の違いを区別しないので等価だ。
MacOS のファイル名は等値性で区別するので、徹底的に正規化され濁点さえも分離される。
SQL Server はデフォルトで片仮名と平仮名、半角と全角を等価であるとみなし区別しない。

まあ、概念の違いはいい、納得してもらったとしよう。

問題は、面接官のいう「等値」と「等価」という言葉に、上記のような(あるいは別の)意味合いで使い分けされている前提があるのか、ということだけれども、現状、ご存知のとおり混乱している。
技術用語として「等値」と「等価」の区別が重要で厳密に定義されていてその知識が問われているなら、どこか資格試験の教科書にでもしっかり書いてあるはずで、それこそググれば正解がすぐに出てくるはずだ。

そうでないなら、質問のための質問であって、そんなに真に受けることでもないのだと思う。

さて、元ネタの元ネタの equality と equivalence の違いというのは、おそらくスコット・メイヤーズのEffective STL という本にある連想コンテナに関連した議論を踏まえている。
↓のあたりで一部英語で読める。
https://books.google.co.jp/books?id=7x2MxvbjGsYC&pg=PT756&dq=effective+C%2B%2B+equality+equivalence&hl=ja&sa=X&ved=0ahUKEwjSqcneuZ_NAhXFJJQKHZHBD94Q6AEILDAA#v=onepage&q=effective%20C%2B%2B%20equality%20equivalence&f=false
今手元にはないけれども、その日本語版では 等値性(equality) と 等価性(equivalence)に訳されていたと思う。

スコット・メイヤーズの Effective C++ を始めとする Effective シリーズは一時期プログラマのバイブル的な必読書で、今のおっさんが若い頃必死こいて勉強したものだ。うがった見方をすれば、面接官の質問の本来の趣旨は、それぐらい読んでないわけないよな、という単なるおっさんのイヤミぐらいなのかもしれない。

ちなみに最初に参照されたブログでの解答例はどれもピント外れなのであまり参考にしない方がいいです。

長文失礼

投稿2016/06/11 11:26

kumazo

総合スコア12

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

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

0

"=="で比較する場合,数値(プリミティブ型)であろうと参照型であろうと同じ挙動をするのではないかと私は考えています.
プリミティブ値の場合は「値そのもの」がメモリ上に入ります.参照型はその実体が置かれている「場所を示す数値」が入っています.
"=="はすなわちこの値同士を比較し(数値同士で型が違えば適切な型に変換して)等しいかどうかを判定しているのだと思います.参照型なら同じ数値を指す=同じものを指している,と捉えて判定します.これで「同じ」」ならば,物自体が同じなので「同一」です.
一方,「論理的に比較」する場合は,この「格納した場所」は問題ではなく,その「指し示す先の実体の内容」に注目します.例え物が違ってもその中身が同じならば「同じ」と判定します.中身の値が同じかどうかを判定するので「同値」です.

例えるならばプリントの類がわかりやすいでしょうか.同じ内容を印刷したプリントを2枚持ってきた場合,この2枚のプリントは物として違うので「同一」ではないですが,書いてある内容は同じ(書いてある内容が一字一句同じである)なので「同値」です.
等値=同一,等価=同値の対応はややこしいですね.大方別の人物が違う日本語をあてて混在したのではないでしょうか・・・.

投稿2015/09/10 00:59

swordone

総合スコア20651

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

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

k499778

2015/09/10 01:25

swordoneさん 回答ありがとうございます。 そうなんですね。 だとしたら意味合いとしては 等値=同一 等価=同値 という解釈でなんとなく合っているんですね。 ==演算子かequalsメソッドによる判定かどうかは置いといて。 同一、同値はそれでも区別できますが。 ただ等値、等価という日本語自体が英語を訳したものであり、JavaScriptとかで使う等値演算子、同値演算子と混在したりしてややこしくなっているといった感じでしょうか。 なんとなくわかってきました。 「論理的に比較」の意味がわからなかったので、その解釈があって助かりました。 そもそもこの質問を投稿したのも 「プログラマーの力量を見極める--面接官になったら尋ねるべき質問実例集」 http://japan.zdnet.com/sp/10things/20409456/ を見て尋ねました。 少しこの質問はどうなのかなあと思ってしまうところではあります。 同値・同一の意味合いで聞いているのなら、同値・同一で聞けばいいし。。 後半はただの個人的感想になってしまいました。 回答ありがとうございました。感謝しています。
guest

0

「等値 = 等価 = 同値」 国語的には同じ意味を持ちます。
Javaの場合、等値演算子(==)を「等価比較」という呼び方で表し始めると混乱が起きると思います。

質問者さんのおっしゃるように、「同一か否か」については判定が特別な場合(実体を特定する時)に限られるので意味的に全く異なりますが、前述の表現は「同じ値かどうか」もしくは「同じ値である」ことを表すので、文脈的によって若干ですが異なります。

ただ異なっても、求めるところが「等価値」ということには変わりありません。

こんなQ&Aがあるのですが、英語(identity, equality)で捉える癖を付けた方が混乱は少ないかもしれません。

似て非なる言語「JavaScript」には、等値演算子(==)と同値演算子(===)という表現があるので、もしかするとそのせいで余計に日本語が混乱している可能性もあります…

どちらにしても、最終的にプログラム的に必要なことがどちらなのか理解することが一番大切だと思います。

投稿2015/09/09 08:15

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

退会済みユーザー

退会済みユーザー

2015/09/09 08:16

あ、でも僕の考え方もすでに言葉が混乱していますね。 書いてみて気が付いてしまいました…失礼しました。
k499778

2015/09/10 00:04

pikovoltさん 回答ありがとうございます。 意外とこの等値、等価は理解が難しいところですね。 確かに等値演算子、同値演算子があるので余計混乱しています。 丁寧な回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問