Java链表的删除操作

刚开始接触java时很长一段时间, 总觉得java链表的删除操作自己写的有bug。

第一个bug版本:

仅接removeByForlist.remove(j)之后应该显示调用i--

 public static void testRemoveByFor() {

        List<Integer> removeByForlist = Lists.newArrayList(1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
        System.out.println(ToStringBuilder.reflectionToString(Joiner.on("").join(removeByForlist)));
        for (Integer i = 0; i < removeByForlist.size(); i++) {
            Integer j = removeByForlist.get(i);
            if (j.equals(1)) {
                removeByForlist.remove(j);
            }
        }

        System.out.println(ToStringBuilder.reflectionToString(Joiner.on("").join(removeByForlist)));

    }
  public static void main(String[] args) {

        testRemoveByFor();

    }

输出结果:
java.lang.String@35718057[value={1,1,1,1,1,1,1,1,1,1},hash=2075774624]
java.lang.String@3f4de7ea[value={1,1,1,1,1},hash=46760945]

第二个bug版本:

首先介绍一下fail-fast: fail-fast 机制是java集合(Collection)中的一种错误机制。 当多个线程对同一个集合的内容进行操作时,就可能会产生  fail-fast 事件。 例如:当某一个线程A通过 iterator 去遍历某集合的过程中,若该集合的内容被其他线程所改变了;那么线程A访问集合时,就会抛出ConcurrentModificationException 异常,产生 fail-fast 事件。这种设计模式原则是与其留下隐患,不如最初就直接拒绝。这就好比有时我们做人一样,有时需要干脆的拒绝他人。

<p><strong>    <span>      <strong style="line-height: 1.5;">        <span style="line-height: 1.5; background-color: #ff0000;"></span>     </strong>    </span>  </strong></p><span style="color:#ff9900;"><strong>   </strong></span>public static void testRemoveByForeach() {

        List<Integer> removeByForeach = Lists.newArrayList(1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
        System.out.println(ToStringBuilder.reflectionToString(Joiner.on("").join(removeByForeach)));

        for(Integer i : removeByForeach){
            removeByForeach.remove(i);
        }

        System.out.println(ToStringBuilder.reflectionToString(Joiner.on("").join(removeByForeach)));

    }

    public static void main(String[] args)
        testRemoveByIterator();
    }

输出结果:
java.lang.String@35718057[value={1,1,1,1,1,1,1,1,1,1},hash=2075774624]
Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
    at java.util.ArrayList$Itr.next(ArrayList.java:831)
    at listTest.Main.testRemoveByForeach(Main.java:55)
    at listTest.Main.main(Main.java:67)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)

<strong>对第二个bug版本官方文档解释如下:</strong>
* <p><a name="fail-fast"/>
 * The iterators returned by this class's {@link #iterator() iterator} and
 * {@link #listIterator(int) listIterator} methods are <em>fail-fast</em>:
 * <strong><span style="color:#FF6666;">if the list is structurally modified at any time after the iterator is
 * created, in any way except through the iterator's own
 * {@link ListIterator#remove() remove} or
 * {@link ListIterator#add(Object) add} methods, the iterator will throw a
 * {@link ConcurrentModificationException}. </span></strong> Thus, in the face of
 * concurrent modification, the iterator fails quickly and cleanly, rather
 * than risking arbitrary, non-deterministic behavior at an undetermined
 * time in the future.



第三个正确版本:

public static void testRemoveByIterator() {

        List<Integer> removeByIterator = Lists.newArrayList(1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
        System.out.println(ToStringBuilder.reflectionToString(Joiner.on("").join(removeByIterator)));

        Iterator<Integer> iterator = removeByIterator.iterator();
        int i = 0;
        while (iterator.hasNext()) {
            Integer next = iterator.next();
            if (next.equals(1)) {
                iterator.remove();
            }
        }

        System.out.println(ToStringBuilder.reflectionToString(Joiner.on("").join(removeByIterator)));

    }

    public static void main(String[] args) {
        testRemoveByIterator();
    }

输出结果:
java.lang.String@2ea0eb2a[value={1,1,1,1,1,1,1,1,1,1},hash=2075774624]
java.lang.String@13b4d41e[value={},hash=0]





郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。