- PR -

primitive型と参照型について

投稿者投稿内容
Kira
ぬし
会議室デビュー日: 2004/10/30
投稿数: 252
投稿日時: 2005-01-22 21:33
いつもお世話になっています。

教えていただきたいのですが、
hashに値を追加する場合はパターンAのように参照型で記憶するべきか
Bのようにint→stringにするべきかどちらがいいのでしょうか?

昔、本で極力newなどでインスタンスを生成することはさけるべきと
書いてあった気がしたため、、、。

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

HashMap hash = new HashMap();
'A
hash.put("key", new Integer(1));
'B
hash.put("key", Integer.parseInt(1));
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2005-01-22 22:45
Mapのputは引数がObject型です。
primitive型は対応していませんので
各型のラッパーのインスタンスをセットする必要があります。
coasm
大ベテラン
会議室デビュー日: 2001/11/26
投稿数: 237
投稿日時: 2005-01-22 22:54
まず最初に、Integer.parseInt はStringをintに変換するものであって、
intをStringに変換するのではありません。
intをStringに変換するのなら、String.valueOf(int)かInteger.toString(int)です。

で、本論ですが、
(1) Stringにすると、新たなオブジェクトの生成が抑制される「場合がある」
(2) しかし大部分の場合、Stringの方がより多くのメモリーを消費する。
(3) int->Integer変換に比べて、int->String変換が遥かに多くの処理を必要とする。
(4) intに戻す場合も、IntegerよりもStringの方が遥かに多くの処理を必要である。
(5) オブジェクトの等不等比較(equals)関しても、Stringが不利である。

というわけで、一般的な結論としては「Integerを使うほうが遥かに良い」です。
詳しく知りたければ、java.lang.Integer と java.lang.String のソースコードを読みましょう。

かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2005-01-22 23:22
そもそもIntegerはintをオブジェクトとして使用する為の
ラッパークラスですので、intをMapにセットするときは
当然Integerに変換しなければいけません。

どうしてもインスタンス生成を抑制したいのであれば
jakarta projectのcommonsあたりに
プリミティブ向けのコレクションがありますので、
そちらを使用してみてはいかがでしょうか。

余談ですがプリミティブ型のラッパークラスの生成は
Javaの実装次第ですが最適化が行われるようです。
new Integer(1) == new Integer(1)がtrueになることもあるそうです。
最適化も行われるので、特に気にしないで
ラッパーのインスタンスを生成すればよいのでは?と思います。
Kira
ぬし
会議室デビュー日: 2004/10/30
投稿数: 252
投稿日時: 2005-01-23 00:03
素早いご返答みなさまありがとうございました。

hash.put("key", Integer.parseInt(1));

hash.put("key", Integer.toString(1));
の間違いでした。

ご迷惑おかけしましたが、皆様の言わんとすることは分かりました。
ありがとうございます。
YOU@IT
ぬし
会議室デビュー日: 2002/03/29
投稿数: 284
お住まい・勤務地: 大阪
投稿日時: 2005-01-23 00:20
個人的は、int値をコレクションに格納したいのであれば、
Stringよりもそのラッパクラスのインスタンスを使います。

Stringは何でも表現できる反面、
・nullの場合を考慮しないといけない
・空文字("")の場合を考慮しないといけない
・文字列の長さがわからない
・どんな文字が入っているかわからない
等、自由度が高すぎて、逆にお決まりのチェックをあちこちに書かなくては
ならなくなるのが非常にやっかいだと思っています。

さらに、システムの開発・保守をしていて
NullPointer、IndexOutOfBounds、NumberFormat...と
Stringの処理に起因する実行時例外に苦しめられることのなんと多いことか。

ですので、数値や日付等、明確に値の意味や形式が決まっている情報を
表現する場合はそれに適した型を使ったほうがいいと思います。
安直に何でもStringは楽ですけどね。

あと、new によるインスタンス生成はあまり神経質なる必要はないと思います。
# 心掛けるのは良いと思いますけどね。
coasm
大ベテラン
会議室デビュー日: 2001/11/26
投稿数: 237
投稿日時: 2005-01-23 00:52
引用:

かつのりさんの書き込み (2005-01-22 23:22) より:

余談ですがプリミティブ型のラッパークラスの生成は
Javaの実装次第ですが最適化が行われるようです。
new Integer(1) == new Integer(1)がtrueになることもあるそうです。



言語仕様上、newは必ず新たな(既存のオブジェクトと==でない)オブジェクトを返さなければならないので、
それは許されません。constructorでそういう最適化をしてはならないのです。
int->String変換でオブジェクト生成を抑制できるのは、それがInteger.toString(int)という
(constructorでない)メソッドで行われるからです。

Java5では、int->Integer変換で同様の最適化を実現するためにInteger.valueOf(int)メソッドが
新設されました。
#っていうか、むしろ今までなかった方が不思議だ・・・

追記:
念のために確認してみたら、Integer.valueOf(int)Java5の日本語ドキュメントには誤訳が
ありますね。(「should」を正しく訳していない)

[ メッセージ編集済み 編集者: coasm 編集日時 2005-01-23 00:59 ]
山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2005-01-23 03:58
>昔、本で極力newなどでインスタンスを生成することはさけるべきと
>書いてあった気がしたため、、、。
実際試してみればわかりますが最近のJVMは良く最適化されているのでオブジェクトの生成や破棄にかかるコストは大変小さいものです。ソケットやファイルIO関連などヒープ外のリソースも必要とするようなオブジェクトでなければバンバン生成してもほとんどパフォーマンスに影響しませんよ。

スキルアップ/キャリアアップ(JOB@IT)