直接来自[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之间。您需要特殊情况下val值为null 防止NullPointerException。
我想知道为什么我们需要特殊情况下val值为null以防止NullPointerException。我可能会理解我们必须使用安全的代码来防止NullPointerException但是那行代码
if (val == null ? it.next() == null : val.equals(it.next()))
与集合迭代无关,而是仅在参数方法中指定val参数。
提前感谢您对上述提及的任何澄清。
答案 0 :(得分:2)
该测试包含两个不同的规则,用于在val
中找到list
:
val
为null
,那么列表元素必须为null
才能匹配(请回想一下,列表可以包含null
个值)val
不是null
,那么val
必须等于(使用.equals()
)列表元素才能匹配如果您在NullPointerException
为val.equals(list.next())
时尝试评估val
,则会出现null
。
该方法可以这样写:
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);
}
}
答案 1 :(得分: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);
}