2

[http://docs.oracle.com/javase/tutorial/collections/interfaces/list.html]から直接

public static <E> void replace(List<E> list, E val, E newVal) {
    for (ListIterator<E> it = list.listIterator(); it.hasNext(); )
        if (val == null ? it.next() == null : val.equals(it.next()))
            it.set(newVal); }

この例で少し注意が必要なのは、valとit.nextの間の同等性テストです。NullPointerExceptionを防ぐために、nullのval値を特殊なケースにする必要があります。

NullPointerExceptionを防ぐために、なぜnullのval値を特殊なケースにする必要があるのか​​疑問に思っています。NullPointerExceptionを防ぐために安全なコードを作成する必要があることは理解できますが、そのコード行は

if (val == null ? it.next() == null : val.equals(it.next()))

はコレクションの反復とは関係ありませんが、代わりにvalパラメーターはparametersメソッドでのみ指定されます。

上記の説明を事前に感謝します。

4

2 に答える 2

2

valこのテストでは、次の場所に配置するための2つの異なるルールがカプセル化されていlistます。

  1. の場合、一致するためにvalnullリスト要素がnull存在する必要があります(リストには値を含めることができることを思い出してくださいnull
  2. でない場合valnull、一致するためにリスト要素valと等しくなければなりません(を使用して).equals()

いつだったNullPointerExceptionかを評価しようとすると、が発生します。val.equals(list.next())valnull

メソッドは次のように記述できます。

public static <E> void replace(List<E> list, E val, E newVal) {
    if (val == null) {
        for (ListIterator<E> it = list.listIterator(); it.hasNext(); )
            if (it.next() == null)
                it.set(newVal);
    } else {
        for (ListIterator<E> it = list.listIterator(); it.hasNext(); )
            if (val.equals(it.next()))
                it.set(newVal);
    }
}
于 2013-03-24T16:24:00.170 に答える
2

ここで起こっていることのあなたの読みは絶対に正しいです:彼らが話している「特別な場合」は、リストの反復ではなく、パラメータのヌルチェックに関連しています。

実際、ifステートメントをループのに移動して、少し効率的ですが読みにくいソリューションにすることができます。

if (val != null) {
    for (ListIterator<E> it = list.listIterator(); it.hasNext(); )
        if (val.equals(it.next()))
            it.set(newVal);
} else {
    for (ListIterator<E> it = list.listIterator(); it.hasNext(); )
        if (it.next() == null)
            it.set(newVal);
}
于 2013-03-24T16:24:34.837 に答える