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