Pythonの’==’と’is’
Pythonで2つの物が同値かどうか確認するには
==を使う方法とisを使う方法がありますが、
これらは少し違うものです。
Immutable 1 なintやstring等の場合には基本的に結果は同じです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |
一方、Mutableなリストとかだと
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
の様に、isの方だと同値とみなしません。
これは、==の方は値を比較しているのに対して、
isの方は同じオブジェクト(同じID、メモリ上のアドレスに対応するもの)かどうかを比較してるからです。
実際IDを見てみると、
1 2 3 4 5 6 7 8 9 | |
な感じでint型の方は1なものは全て同じIDですが、
listの方では値が同じでもIDはそれぞれ違っています。
Javaの’==’と’equals’について
Javaの型にはプリミティブ型と呼ばれる基本的な方が有り、
byte, short, int, long, float, double, char, boolean
の基本的な型で小文字で始める型です。
これらに関しては==で同値かどうか判断します。
一方、String等はオブジェクトで、
オブジェクトは全てequalsというメソッドを持っています。
このequalsはデフォルトで
1 2 3 | |
という風に定義されていて、==と同じです。
で、この==は、オブジェクトの参照先が同じものかどうか、でtrue or falseを返します。
なので、String型とかでも、同じ文字列を持つものでも
==で判断すると違うオブジェクトであれば違うものと判断されます。
同じ内容かどうか、を判断するために、
String型ではequalsメソッドをオーバーライドして
文字列の内容が同じかどうか、を返す様にしてあります。
1 2 3 4 5 6 7 8 | |
とすると
s1.equals(s2)
だけ表示されます。
ただ、次の様にnewを使わずに直接文字列を入れるようにすると
1 2 3 4 5 6 7 8 | |
とすると
s1 == s2
s1.equals(s2)
と両方表示されます。
この場合はインスタンス化されてない文字列が擬似プリミティブ型と呼ばれ、
"abc"がs1, s2両方で同じオブジェクトを指す様な形になるので
s1 == s2でもtrueになります。
ですが、普通に文字列の比較をしたい場合には
必ずequalsで比較するべきです。
これと同じように、数字でもInteger型を使う時には
==で比較するとおかしくなることがあります。
1 2 3 4 5 6 7 8 | |
とすると
i1.equals(i2)
なのでIntegerを比較する際にもequalsを使います。
Integerに直接数字を入れて
1 2 3 4 5 6 7 8 | |
比較すると
i1 == i2
i1.equals(i2)
となります。
ただ、これは数値が-128から127までの間の場合だけで、
この間ではこれらの数字がおあんじオブジェクトとして扱われますが、
それ以上になるとIntegerに入れる時はインスタンス化されるので
1 2 3 4 5 6 7 8 | |
比較すると
i1.equals(i2)
の様にequalsだけがtrueを返します。
まとめ
Pythonの場合もJavaの場合も最初の頃良くわからないまま
適当にやってしまうところですが、
両方見てみると==の意味合いが
逆な感じになってるのでちょっと混乱の元です。
というかちょっと混乱したのでまとめておきました。
- Pythonで値を比較する時は
isではなく==。 - JavaのStringやInteger等で値を比較する時は
==ではなくequals。
