web-dev-qa-db-ja.com

なぜJavaコレクションはプリミティブ型を直接保存しないのですか?

Javaコレクションは、プリミティブ型ではなく、オブジェクトのみを保存します。ただし、ラッパークラスは保存できます。

なぜこの制約があるのですか?

112
JavaUser

これはJava設計上の決定であり、一部の人は間違いと考えるものです。コンテナはオブジェクトとプリミティブをオブジェクトから派生させたくないのです。

これは、.NETデザイナーがJVMから学んだ1つの場所であり、多くの場合、ボクシングが排除されるように値の型とジェネリックを実装しました。 CLRでは、ジェネリックコンテナーは、基になるコンテナー構造の一部として値型を格納できます。

Javaは、JVMからのサポートなしで、コンパイラーに汎用サポートを100%追加することを選択しました。 JVMはそれが何であるか、「非オブジェクト」オブジェクトをサポートしていません。 Javaジェネリックを使用すると、ラッパーがないふりをすることができますが、ボクシングのパフォーマンスの代価を支払うことになります。これは特定のクラスのプログラムにとって重要です。

ボクシングは技術的な妥協であり、実装の詳細が言語に漏れていると感じています。オートボクシングは優れた構文上の砂糖ですが、それでもパフォーマンスが低下します。どちらかといえば、コンパイラが自動ボックス化するときに警告を発してほしい。 (私が知っている限り、2010年にこの答えを書いたかもしれません)。

SOボクシングについての良い説明: なぜ一部の言語はボクシングとアンボクシングが必要なのですか?

そして、Javaジェネリックの批判: なぜJavaのジェネリックの実装が悪いと主張するのですか?

Javaの防御では、後向きになって批判するのは簡単です。 JVMは時の試練に耐え、多くの点で優れた設計です。

86
codenheim

実装を簡単にします。 Javaプリミティブはオブジェクトと見なされないため、これらのプリミティブごとに個別のコレクションクラスを作成する必要があります(共有するテンプレートコードはありません)。

もちろん、 GNU TroveApache Commons Primitives または [〜#〜] hppc [〜#〜] を参照してください。

本当に大きなコレクションがない限り、ラッパーのオーバーヘッドは人々が気にするのに十分ではありません(そして、あなたが本当に大きなプリミティブコレクションを持っているとき、あなたはそれらのための特別なデータ構造の使用/構築に努力を費やすことができます)。

15
Thilo

それは2つの事実の組み合わせです:

  • Javaプリミティブ型は参照型ではありません(たとえば、intObjectではありません)
  • Javaは、参照型の型消去(たとえば、List<?>は本当にList<Object>実行時)

これらは両方とも真であるため、ジェネリックJavaコレクションはプリミティブ型を直接保存できません。便宜上、オートボクシングが導入され、プリミティブ型を参照型として自動的にボックス化できるようになりました。ただし、コレクションには関係なくオブジェクト参照が保存されます。

これは回避できたでしょうか?おそらく。

  • intObjectである場合、ボックスタイプはまったく必要ありません。
  • 型消去を使用してジェネリックが行われない場合、プリミティブが型パラメーターに使用されている可能性があります。
11

auto-boxing およびauto-unboxingの概念があります。 intList<Integer>に保存しようとすると、Javaコンパイラは自動的にIntegerに変換します。

7
Jeremy

それは本当に制約ではありませんか?

プリミティブ値を格納するコレクションを作成するかどうかを検討してください。 int、float、charのいずれかを格納できるコレクションをどのように作成しますか?ほとんどの場合、複数のコレクションになるため、intlistやcharlistなどが必要になります。

Javaのオブジェクト指向の性質を利用して、任意のオブジェクトを格納できるため、1つのコレクションクラスのみが必要です。この概念、ポリモーフィズムは非常に強力であり、設計を大幅に簡素化します。ライブラリの。

3

主な理由はJava設計戦略。++ 1)コレクションは操作のためにオブジェクトを必要とし、プリミティブはオブジェクトから派生しないため、これが他の理由になる可能性があります。 2)Javaプリミティブデータ型は参照型ではありません。intはオブジェクトではありません。

克服するために:-

自動ボクシングと自動アンボクシングの概念があります。したがって、プリミティブデータ型を保存しようとすると、コンパイラは自動的にプリミティブデータクラスのオブジェクトに変換します。

0
user5693566

Java 10 http://openjdk.Java.net/jeps/218

今日のコレクションでプリミティブのボクシングを避けたい場合は、いくつかのサードパーティの選択肢があります。前述のサードパーティオプションに加えて、 Eclipse CollectionsFastUtil 、および Koloboke もあります。

プリミティブマップの比較も、タイトル:Large HashMap overview: JDK、FastUtil、Goldman Sachs、HPPC、Koloboke、Trove というタイトルで公開されました。 GS Collections(Goldman Sachs)ライブラリはEclipse Foundationに移行され、現在はEclipse Collectionsになっています。

0
Donald Raab