流量控制,实现替换方法列表

时间:2013-03-24 16:19:24

标签: java iterator nullpointerexception

直接来自[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参数。

提前感谢您对上述提及的任何澄清。

2 个答案:

答案 0 :(得分:2)

该测试包含两个不同的规则,用于在val中找到list

  1. 如果valnull,那么列表元素必须为null才能匹配(请回想一下,列表可以包含null个值)
  2. 如果val不是null,那么val必须等于(使用.equals())列表元素才能匹配
  3. 如果您在NullPointerExceptionval.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);
}