java.util.ArrayListでnullを追加できるのはなぜですか?


41

なぜjava.util.ArrayList追加できるのだろうかnull。に追加nullしたいケースはありますArrayListか?

プロジェクトにバグがあり、そこにコードが追加さnullれていて、バグの場所ArrayListを見つけるのが難しいため、この質問をしています。明らかにa NullPointerExceptionがスローされましたが、他のコードが要素にアクセスしようとするまではスローされませんでした。問題は、nullオブジェクトを追加したコードを見つける方法でした。ArrayList要素が追加されているコードで例外をスローすると、もっと簡単になります。


12
グアバプロジェクトがあり、そのトピックにはかなり興味深いページを(彼らは許可しないnull彼らのコレクションのほとんどで)。
ヨアヒムザウアー

6
ここで与えられた答えは質問をうまくカバーしていると思います。言及すべきことの1つは、JDKに含まれるすべてのものをひどく完璧なものと見なしてはいけません。いくつかの事柄は(正直なところ、私見)間違いであり、後方互換性のためにそこに残りました。Javaの作成者でさえ認めていますが、Joshua Blochの本を読んで、特定のJava APIに対する彼の批判を見てください。とにかく、あなたの質問は天気に帰着します。JavaでNPEをキャッチするよりエレガントな方法はありません。答えは「いいえ」ですが、あるはずです。
シヴァンドラゴン

2
許可されない理由に関する詳細情報を提供できますか?それが単なる好みの問題である場合、制限の少ない方が好まれます。
マーレInfinitus 14

簡単な答えは、それnullがJavaで欠落データを表すデフォルトの方法であるということです。実際、多くの人々はそれを好まないため、関数型プログラミングスタイルのことの議論にしています。最も賛成の答えは意味がありません/問題の本質を把握していません。
-xji

@JIXiangあなたは何を単純化しすぎていますnull。「欠落」は、のいくつかの潜在的な解釈の1つにすぎませんnull。他の有効な解釈は、「不明」、「適用外」、または「初期化されていない」です。何をnull表すかはアプリケーションによって異なります。Pythonコミュニティが言うように、「あいまいさに直面して、推測する誘惑を拒否します。」nullを完全に保持できるコンテナでnullを保持することを拒否することは、まさにそれです。
リウォーク

回答:


34

この設計上の決定は、主にネーミングによって決定されます。

ArrayListという名前は、読者に配列に似た機能を提案します。JavaCollections Frameworkの設計者は、大部分のAPIユーザーが配列に似た機能に依存することを期待するのが自然です。

特に、これにはヌル要素の処理が含まれます。以下が正常に機能することを知っているAPIユーザー:

array[0] = null; // NPE won't happen here

ArrayListの同様のコードがNPEをスローするかどうかを知ることは非常に驚きです。

arrayList.set(0, null); // NPE => WTF?

上記のような推論は、ArrayListとプレーン配列の密接な類似性を示唆するポイントを強調するJCFチュートリアルに示されています。

ArrayList ...は、一定時間の位置アクセスを提供し、単純に高速です...

List実装でnullを許可しない場合はNonNullableArrayList、APIユーザーの混乱を避けるために、次のように呼び出すことをお勧めします。


補足説明として、以下のコメントに補足説明があり、ここで説明されている推論をサポートする追加の考慮事項があります。


12
リストのエントリLinkedList サポートしていることを考えると、この説明は納得できませんnull
スティーブンC

12
うん...しかし、より単純で(IMO)よりもっともらしい説明は、nullエントリーを許可することが多くの場合に役立つということです。
スティーブンC 14

7
ArrayListは、配列を模倣するため、そのようには呼び出されません。配列として実装されたリストであるため、そのように呼ばれます。TreeMapがTreeのように動作しないように。
フロリアンF

11
この答え、IMOは、まったく間違っています。Javaでは、良くも悪くも(IMO、さらに悪いことに)初期化されていない値や欠損値を表すためにnullが頻繁に使用されるため、nullが許可されます。どのようにして、最も多くの票と「承認」チェックを獲得しましたか?真剣に、私は最近StackOverflowに対する信頼を本当に失いつつあります。
user949300 14

8
この答えは間違いです。これは、リスト実装で許可されているヌルに関するサポートされていない推測です。以下は、nullを許可/禁止するJavaコレクションのまとめです。配列との類似性とは何の関係もないことに注意してください。
アンドレスF。14年

32

Nullは、リストの要素の有効な値である可能性があります。リストには、ユーザーのリストに関するオプションのデータを表す要素が含まれており、ユーザーと同じ順序で保存されているとします。追加データが入力されている場合、リストには追加データが含まれます。そうでない場合、ユーザーに対応するスロットはnullになります。(より良い例はあると思いますが、あなたはそのアイデアを得ます)

nullの追加を許可したくない場合は、nullが追加されたときにスローした独自のラッパーで配列リストをラップできます。


2
これは、nullを許可する理由の悪い例のように思えます。リストでnull値を使用するよりも、オプションのデータを表現するより良い方法があります。
カサブランカ

@casablancaええ完全に同意します、それは素晴らしい例ではありません。
サムホルダー

ArrayListにnullが含まれる正当な理由を見つけることができません。それ以外に、次の開発者がそれを「発見」するのは悪い驚きです:/
AndreasScheinert

7
@casablancaオプションのデータを表現するために、nullは避けるべきであることに同意しますが、Javaでは、良くも悪くも「伝統的」です。
user949300 14

2
堅実なユースケース:パラメータを動的関数にリストとして渡したい場合。複数の関数があり、それぞれに異なるパラメーターのセットがあるため、動的なサイズの配列が必要であり、有効な関数の引数として常にnullを渡すことができます!
ファルコ

19

ArrayList設計上nullを許可します。意図的です。javadocから:

「[ArrayListはa]リストインターフェイスのresizable-array実装です。すべてのオプションのリスト操作を実装し、nullを含むすべての要素を許可します。」

「なぜ」に対する答えnullは、リストにaを入れる必要がある場合にArrayListを使用できなかった場合です。対照的に、値を追加する前に値をテストするか、これを防ぐラッパーを使用することにより、ArrayListにnullが含まれないようにすることができます。

ArrayListにnullを追加したい場合はありますか?

明らかに、どのケースにnullも明確な意味があります。たとえば、リスト内の特定の位置の値が初期化されていないか、提供されていないことを意味する場合があります。

ArrayListが要素が追加されているコードで例外をスローしていたとしたらもっと簡単だったでしょう。

ラッパークラスを作成することで、その動作を簡単に実装できます。ただし、これはほとんどのプログラマ/アプリケーションが必要とする動作ではありません。


8

ArrayListにnullを追加したい場合はありますか?

もちろん、事前割り当てはどうですか?あなたが欲しいArrayListあなたが十分な情報を持っていないので、あなたがまだ作成することはできません物事のを。誰かが何かをしたい理由を考えることができないからといって、それが悪い考えになるわけではありません。なんでも。(今、誰か​​がやって来て、代わりにあなたがいくつかのあいまいなブログで読んだパターンを満たす空のオブジェクトを持っているべきだと言うと確信しています、そしてプログラマーはif文を使わずにプログラムを書くことができるはずです。

nullコンテナにs が存在してはならないという契約を結んでいる場合、おそらく最も適切にアサートすることで、契約が維持されることを確認するのはあなた次第です。おそらく最大10行のコードが必要でした。Javaを使用すると、この種のことが非常に簡単になります。JDKはあなたの心を読むことができません。


1
ensureCapacity(int minCapacity)メソッドとArrayList(int initialCapacity)コンストラクターを使用して既にArrayListに組み込まれているため、事前割り当て引数は無効です。
フィリップ14

7
@Philippその空間にどんな価値を置くのでしょうか?
ジェームズ14

明らかな選択はnull、の事前に割り当てられた(ただしまだ使用されていない)エントリにを入れることArrayListです。しかし、それをensureCapacityやらせることはできますが、それ以外の機能を許可することはできませんset。他の場所で与えられた理由はより強く見える。
デビッドK 14年

@DavidK:setによって返される可能性のある任意の値へのアイテムが可能であるべきだと言うのは理にかなっていますget。通常の試みとしてもgetスペースが割り当てられていないが、決して書かれていたために項目が帰国するのではなく、例外をスローする必要がありnull、まだ可能となるメソッドのペア持つことが有用であろうlist1.setOrEraseIfNull(index, list2.getOrReturnNull(index))という要求するのではなくif (list2.valueSet(index)) list1.set(index, list2.get(index)); else list1.unset(index);
supercat

1
@DavidK:割り当てられているがまだ書き込まれていないエントリを読み取ろうとすると、nullが生成されるか、例外がスローされます。nullを返す方が簡単です。
supercat

4

これは、ここでは(ソフトウェア)哲学的な質問のようです。

ArrayList ユーティリティクラスは、考えられるユースケースの幅広いコンテキストで役立つように設計されているためです。

nullを有効な値として受け入れることは推奨されないという隠れた主張に反して、null値が完全に合法である多くの例があります。

最も重要な理由の1つnullは、do not knowフレームワークタイプを含むあらゆる参照タイプと同等であることです。これは、どのような場合でも、より流beなバージョンのnothing値でnullを置き換えることができないことを意味します。

したがって、配列リストの対応するインデックスに整数1、3、7を格納するとしましょう。何らかの計算のために、インデックス5の要素を取得したいので、配列が返す値は「no value stored」です。これは、nullまたはNullObjectを返すことで実現できます。ほとんどの場合、組み込みのnull値を返すことで十分な表現力が得られます。nullを返すことができるメソッドを呼び出し、その戻り値を使用した後、nullに対する戻り値のチェックは、現代のコードでは非常に一般的です。


4

声明

File f = null;

有効で便利です(理由を説明する必要はないと思います)。同様に、いくつかのファイルがヌルである可能性のあるファイルのコレクションがあると便利です。

List<File> files = new ArrayList<File>();
// use my collection of files
// ....
// not using this one anymore:
files.set(3, null);

nullオブジェクトを含む可能性のあるコレクションの有用性は、nullである可能性のあるオブジェクトの有用性から直接進んでいます。それは本当に簡単です。


2

制限するよりも、事実を受け入れてからデザインを開いてみるよりも、すべてを受け入れる方が簡単です。

たとえば、oracle / sunがNonNullableArrayListのみを提供したが、リストにNullを追加できるようにしたい場合はどうでしょう。どうしますか?おそらくまったく異なるオブジェクトを作成する必要があり、NonNullableArrayListを拡張することはできません。代わりに、すべてを取るArrayListがある場合、それを簡単に拡張し、null値を受け入れないaddをオーバーライドできます。


2
同意しませんでした。誤用が広範に使用されるようになると、許可しすぎると修正が難しくなります。言語設計者が後の段階でヌルを許可した場合、既存のプログラムを壊すことはありませんが、その反対は真実ではありません。
アンドレスF.

2
しかし、私は同意します。機能の最大化です。nullを必要としない場合でも、nullを受け入れるリストを使用できます。nullが必要な場合は、nullを拒否するリストを使用できません。
フロリアンF

-1

nullの有用性?

リストのリストを使用して、さまざまな位置の2Dリアルライフプレートをモデル化する場合、非常に重要です。これらの位置の半分は(ランダムな座標で)空になる可能性がありますが、塗りつぶされた位置は単純なintStringではなく、複雑なオブジェクトによって表されます。位置情報を保持する場合は、list.get(x).get(y)のように空のスポットをnullで埋める必要があります厄介な驚きにつながることはありません。null例外に対処するには、nullをチェックするか(非常に一般的)、またはOptionalを使用します(この場合に便利です)。別の方法としては、空のスポットを「ジャンク」オブジェクトで埋めて、あらゆる種類の混乱を引き起こす可能性があります。nullチェックが失敗するか、どこかで忘れられた場合、Javaが知らせてくれます。一方、適切にチェックされない「ジャンク」プレースホルダオブジェクトは、気付かれずに通過する可能性があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.