SubList到底怎么转化为ArrayList?

2019/04/10 10:10
阅读数 9

<section id="nice" data-tool="mdnice编辑器" data-website="https://www.mdnice.com" style="font-size: 16px; color: black; padding: 10px; line-height: 1.6; word-spacing: 0px; letter-spacing: 0px; word-break: break-word; word-wrap: break-word; text-align: left; font-family: PingFangSC-Light;"><h2 data-tool="mdnice编辑器" style="margin-top: 40px; margin-bottom: 20px; font-weight: bold; color: black; font-size: 24px; text-align: left; margin: 20px 10px 0px 0px;"><span style="font-family: STHeitiSC-Light; font-size: 18px; font-weight: bolder; display: inline-block; padding-left: 10px; border-left: 5px solid rgb(248,57,41);">SubList</span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; color: black; margin: 10px 10px; line-height: 1.75; letter-spacing: 0.2em; font-size: 14px; word-spacing: 0.1em;">大家好,今天 Tony 给大家讲个<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgb(271,93,108);">SubList</code>转化的坑。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; color: black; margin: 10px 10px; line-height: 1.75; letter-spacing: 0.2em; font-size: 14px; word-spacing: 0.1em;">这个错误真的会被忽略,大家好好的看看,这个错误我们生产环境还真的遇到过。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; color: black; margin: 10px 10px; line-height: 1.75; letter-spacing: 0.2em; font-size: 14px; word-spacing: 0.1em;">集合类型相信大家都很熟悉,在 Java 中 ArrayList 使用的场景非常普遍。我们今天主要看的是 ArrayList 中的 subList 方法。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; color: black; margin: 10px 10px; line-height: 1.75; letter-spacing: 0.2em; font-size: 14px; word-spacing: 0.1em;">首先我们来看看源码</p> <blockquote data-tool="mdnice编辑器" style="display: block; font-size: 0.9em; overflow: auto; overflow-scrolling: touch; padding-top: 10px; padding-bottom: 10px; padding-left: 20px; padding-right: 10px; margin-bottom: 20px; margin-top: 20px; font-style: normal; border-left: none; padding: 10px; position: relative; line-height: 1.8; border-radius: 0px 0px 10px 10px; color: #FEEEED; background: #000; box-shadow: #84A1A8 0px 10px 15px;"><span style="display: inline; color: #FFF; font-size: 4em; font-family: Arial,serif; line-height: 1em; font-weight: 700;"> </span> <p style="padding-top: 8px; padding-bottom: 8px; letter-spacing: 0.2em; word-spacing: 0.1em; margin: 0px; line-height: 26px; color: #FEEEED; font-size: 13px; display: inline;">Returns a view of the portion of this list between the specified {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.</p> <span style="float: right; display: inline; color: #FFF; font-size: 3em; line-height: 1em; font-weight: 500;">”</span></blockquote> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; color: black; margin: 10px 10px; line-height: 1.75; letter-spacing: 0.2em; font-size: 14px; word-spacing: 0.1em;">在 jdk 的源码中清楚的写明了返回的是一个<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgb(271,93,108);">new SubList</code>,方法的注释上面写的是返回一个 View,可以理解为视图。</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; background: #fff; color: black; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;"><span class="hljs-function" style="line-height: 26px;"><span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">public</span> List&lt;E&gt; <span class="hljs-title" style="color: #1c00cf; line-height: 26px;">subList</span><span class="hljs-params" style="color: #5c2699; line-height: 26px;">(<span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">int</span> fromIndex, <span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">int</span> toIndex)</span> </span>{ subListRangeCheck(fromIndex, toIndex, size); <span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">return</span> <span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">new</span> SubList(<span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">this</span>, <span class="hljs-number" style="color: #1c00cf; line-height: 26px;">0</span>, fromIndex, toIndex); } </code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; color: black; margin: 10px 10px; line-height: 1.75; letter-spacing: 0.2em; font-size: 14px; word-spacing: 0.1em;">接下来我们再细品<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgb(271,93,108);">SubList</code>,源码</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; background: #fff; color: black; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;"> private class SubList extends AbstractList&lt;E&gt; implements RandomAccess { private final AbstractList&lt;E&gt; parent; private final int parentOffset; private final int offset; int size;

  SubList(AbstractList&lt;E&gt; parent,
          int offset, int fromIndex, int toIndex) {
      this.parent = parent;
      this.parentOffset = fromIndex;
      this.offset = offset + fromIndex;
      this.size = toIndex - fromIndex;
      this.modCount = ArrayList.this.modCount;

} } </code></pre>

<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; color: black; margin: 10px 10px; line-height: 1.75; letter-spacing: 0.2em; font-size: 14px; word-spacing: 0.1em;">SubList 是 ArrayList 中的一个内部类,继承了 AbstractList,实现了 RandomAccess,从上面的代码中可以看到,在 SubList 这个构造方法中还是直接引用的父类中的元素,只是单纯的将截取的索引重新赋值了一下。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; color: black; margin: 10px 10px; line-height: 1.75; letter-spacing: 0.2em; font-size: 14px; word-spacing: 0.1em;">使用场景</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; background: #fff; color: black; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;"> <span class="hljs-function" style="line-height: 26px;"><span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">public</span> <span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">static</span> <span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">void</span> <span class="hljs-title" style="color: #1c00cf; line-height: 26px;">main</span><span class="hljs-params" style="color: #5c2699; line-height: 26px;">(String[] args)</span> </span>{ List&lt;String&gt; names = <span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">new</span> ArrayList&lt;String&gt;() {{ add(<span class="hljs-string">"兔子"</span>);add(<span class="hljs-string">"托尼"</span>);add(<span class="hljs-string">"`啊"</span>); }}; List&lt;String&gt; subList = names.subList(<span class="hljs-number" style="color: #1c00cf; line-height: 26px;">0</span>, <span class="hljs-number" style="color: #1c00cf; line-height: 26px;">3</span>); System.out.println(subList); } </code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; color: black; margin: 10px 10px; line-height: 1.75; letter-spacing: 0.2em; font-size: 14px; word-spacing: 0.1em;">上面的代码输出结果</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; background: #fff; color: black; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;">[兔子, 托尼, 啊] </code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; color: black; margin: 10px 10px; line-height: 1.75; letter-spacing: 0.2em; font-size: 14px; word-spacing: 0.1em;">在什么情况下会报错呢?接下来再看个例子,把上面的代码简单修改下,让数据返回 ArrayList</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; background: #fff; color: black; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;"> <span class="hljs-function" style="line-height: 26px;"><span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">public</span> <span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">static</span> <span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">void</span> <span class="hljs-title" style="color: #1c00cf; line-height: 26px;">main</span><span class="hljs-params" style="color: #5c2699; line-height: 26px;">(String[] args)</span> </span>{ List&lt;String&gt; names = <span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">new</span> ArrayList&lt;String&gt;() {{ add(<span class="hljs-string">"兔子"</span>);add(<span class="hljs-string">"托尼"</span>);add(<span class="hljs-string">"啊"</span>); }}; ArrayList&lt;String&gt; subList = (ArrayList)names.subList(<span class="hljs-number" style="color: #1c00cf; line-height: 26px;">0</span>, <span class="hljs-number" style="color: #1c00cf; line-height: 26px;">3</span>); System.out.println(subList); } </code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; color: black; margin: 10px 10px; line-height: 1.75; letter-spacing: 0.2em; font-size: 14px; word-spacing: 0.1em;">上面的代码直接抛出异常了</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; background: #fff; color: black; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;">Exception in thread <span class="hljs-string" style="color: #c41a16; line-height: 26px;">"main"</span> java.lang.ClassCastException: java.util.ArrayList$SubList cannot be cast to java.util.ArrayList </code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; color: black; margin: 10px 10px; line-height: 1.75; letter-spacing: 0.2em; font-size: 14px; word-spacing: 0.1em;">为什么不能直接转换为 ArrayList 呢?上面的源码已经显示了,SubList 只是一个内部类,它继承 AbstractList 和 ArrayList 根本都没有关系,所以直接转化会报 Cast 异常。</p> <h2 data-tool="mdnice编辑器" style="margin-top: 40px; margin-bottom: 20px; font-weight: bold; color: black; font-size: 24px; text-align: left; margin: 20px 10px 0px 0px;"><span style="font-family: STHeitiSC-Light; font-size: 18px; font-weight: bolder; display: inline-block; padding-left: 10px; border-left: 5px solid rgb(248,57,41);">ModificationException</span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; color: black; margin: 10px 10px; line-height: 1.75; letter-spacing: 0.2em; font-size: 14px; word-spacing: 0.1em;">SubList 同样具有集合原始的方法比如添加、删除等。我截取部分源码。</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; background: #fff; color: black; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;"> <span class="hljs-function" style="line-height: 26px;"><span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">public</span> E <span class="hljs-title" style="color: #1c00cf; line-height: 26px;">set</span><span class="hljs-params" style="color: #5c2699; line-height: 26px;">(<span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">int</span> index, E e)</span> </span>{ rangeCheck(index); checkForComodification(); E oldValue = ArrayList.<span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">this</span>.elementData(offset + index); ArrayList.<span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">this</span>.elementData[offset + index] = e; <span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">return</span> oldValue; }

<span class="hljs-function" style="line-height: 26px;"><span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">public</span> E <span class="hljs-title" style="color: #1c00cf; line-height: 26px;">get</span><span class="hljs-params" style="color: #5c2699; line-height: 26px;">(<span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">int</span> index)</span> </span>{ rangeCheck(index); checkForComodification(); <span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">return</span> ArrayList.<span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">this</span>.elementData(offset + index); }

<span class="hljs-function" style="line-height: 26px;"><span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">public</span> <span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">int</span> <span class="hljs-title" style="color: #1c00cf; line-height: 26px;">size</span><span class="hljs-params" style="color: #5c2699; line-height: 26px;">()</span> </span>{ checkForComodification(); <span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">return</span> <span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">this</span>.size; }

<span class="hljs-function" style="line-height: 26px;"><span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">public</span> <span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">void</span> <span class="hljs-title" style="color: #1c00cf; line-height: 26px;">add</span><span class="hljs-params" style="color: #5c2699; line-height: 26px;">(<span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">int</span> index, E e)</span> </span>{ rangeCheckForAdd(index); checkForComodification(); parent.add(parentOffset + index, e); <span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">this</span>.modCount = parent.modCount; <span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">this</span>.size++; }

<span class="hljs-function" style="line-height: 26px;"><span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">public</span> E <span class="hljs-title" style="color: #1c00cf; line-height: 26px;">remove</span><span class="hljs-params" style="color: #5c2699; line-height: 26px;">(<span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">int</span> index)</span> </span>{ rangeCheck(index); checkForComodification(); E result = parent.remove(parentOffset + index); <span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">this</span>.modCount = parent.modCount; <span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">this</span>.size--; <span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">return</span> result; }

<span class="hljs-function" style="line-height: 26px;"><span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">protected</span> <span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">void</span> <span class="hljs-title" style="color: #1c00cf; line-height: 26px;">removeRange</span><span class="hljs-params" style="color: #5c2699; line-height: 26px;">(<span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">int</span> fromIndex, <span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">int</span> toIndex)</span> </span>{ checkForComodification(); parent.removeRange(parentOffset + fromIndex, parentOffset + toIndex); <span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">this</span>.modCount = parent.modCount; <span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">this</span>.size -= toIndex - fromIndex; }

</code></pre>

<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; color: black; margin: 10px 10px; line-height: 1.75; letter-spacing: 0.2em; font-size: 14px; word-spacing: 0.1em;">上面的源码中每一个方法都包含有一个<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgb(271,93,108);">checkForComodification</code> 方法。 这个方法是有什么作用呢?</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; background: #fff; color: black; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;"><span class="hljs-function" style="line-height: 26px;"><span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">private</span> <span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">void</span> <span class="hljs-title" style="color: #1c00cf; line-height: 26px;">checkForComodification</span><span class="hljs-params" style="color: #5c2699; line-height: 26px;">()</span> </span>{ <span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">if</span> (ArrayList.<span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">this</span>.modCount != <span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">this</span>.modCount) <span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">throw</span> <span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">new</span> ConcurrentModificationException(); } </code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; color: black; margin: 10px 10px; line-height: 1.75; letter-spacing: 0.2em; font-size: 14px; word-spacing: 0.1em;">源码中写的很清楚,判断原始类型,可以理解为父类型原始的 ArrayList 和当前的 SubList 方法中的元素个数做比较,如果不一样就报异常。 1、 对 subList 视图做数据的删除</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; background: #fff; color: black; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;"><span class="hljs-function" style="line-height: 26px;"><span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">public</span> <span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">static</span> <span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">void</span> <span class="hljs-title" style="color: #1c00cf; line-height: 26px;">main</span><span class="hljs-params" style="color: #5c2699; line-height: 26px;">(String[] args)</span> </span>{ List&lt;String&gt; namesList = <span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">new</span> ArrayList&lt;String&gt;() {{ add(<span class="hljs-string">"兔子"</span>); add(<span class="hljs-string">"托尼"</span>); add(<span class="hljs-string">"啊"</span>); }}; System.out.println(<span class="hljs-string" style="color: #c41a16; line-height: 26px;">"namesList原始的:== ==&gt;"</span> + namesList); List&lt;String&gt; subList = namesList.subList(<span class="hljs-number" style="color: #1c00cf; line-height: 26px;">0</span>, <span class="hljs-number" style="color: #1c00cf; line-height: 26px;">2</span>); System.out.println(<span class="hljs-string" style="color: #c41a16; line-height: 26px;">"subList截取的:== ==&gt;"</span> + subList); <span class="hljs-comment" style="color: #007400; line-height: 26px;">//删除SubList第2个元素</span> subList.remove(<span class="hljs-number" style="color: #1c00cf; line-height: 26px;">1</span>); System.out.println(<span class="hljs-string" style="color: #c41a16; line-height: 26px;">"subList删除的:== ==&gt;"</span> + subList); System.out.println(<span class="hljs-string" style="color: #c41a16; line-height: 26px;">"namesList删除的:== ==&gt;"</span> + namesList); } </code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; color: black; margin: 10px 10px; line-height: 1.75; letter-spacing: 0.2em; font-size: 14px; word-spacing: 0.1em;">上面的代码运行正常输出结果</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; background: #fff; color: black; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;">namesList原始的:== ==&gt;[兔子, 托尼, 啊] subList截取的:== ==&gt;[兔子, 托尼] subList删除的:== ==&gt;[兔子] namesList删除的:== ==&gt;[兔子, 啊] </code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; color: black; margin: 10px 10px; line-height: 1.75; letter-spacing: 0.2em; font-size: 14px; word-spacing: 0.1em;">2、 对 ArrayList 做数据的删除</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; background: #fff; color: black; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;"> <span class="hljs-function" style="line-height: 26px;"><span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">public</span> <span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">static</span> <span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">void</span> <span class="hljs-title" style="color: #1c00cf; line-height: 26px;">main</span><span class="hljs-params" style="color: #5c2699; line-height: 26px;">(String[] args)</span> </span>{ List&lt;String&gt; namesList = <span class="hljs-keyword" style="color: #aa0d91; line-height: 26px;">new</span> ArrayList&lt;String&gt;() {{ add(<span class="hljs-string">"兔子"</span>); add(<span class="hljs-string">"托尼"</span>); add(<span class="hljs-string">"啊"</span>); }}; System.out.println(<span class="hljs-string" style="color: #c41a16; line-height: 26px;">"namesList原始的:== ==&gt;"</span> + namesList); List&lt;String&gt; subList = namesList.subList(<span class="hljs-number" style="color: #1c00cf; line-height: 26px;">0</span>, <span class="hljs-number" style="color: #1c00cf; line-height: 26px;">2</span>); System.out.println(<span class="hljs-string" style="color: #c41a16; line-height: 26px;">"subList截取的:== ==&gt;"</span> + subList); <span class="hljs-comment" style="color: #007400; line-height: 26px;">//删除ArraList第2个元素</span> namesList.remove(<span class="hljs-number" style="color: #1c00cf; line-height: 26px;">1</span>); System.out.println(<span class="hljs-string" style="color: #c41a16; line-height: 26px;">"subList删除的:== ==&gt;"</span> + subList); System.out.println(<span class="hljs-string" style="color: #c41a16; line-height: 26px;">"namesList删除的:== ==&gt;"</span> + namesList); } </code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; color: black; margin: 10px 10px; line-height: 1.75; letter-spacing: 0.2em; font-size: 14px; word-spacing: 0.1em;">输出结果报异常了</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; background: #fff; color: black; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;">namesList原始的:== ==&gt;[兔子, 托尼, 啊] subList截取的:== ==&gt;[兔子, 托尼] Exception in thread <span class="hljs-string" style="color: #c41a16; line-height: 26px;">"main"</span> java.util.ConcurrentModificationException at java.util.ArrayList$SubList.checkForComodification(ArrayList.java:<span class="hljs-number" style="color: #1c00cf; line-height: 26px;">1231</span>) at java.util.ArrayList$SubList.listIterator(ArrayList.java:<span class="hljs-number" style="color: #1c00cf; line-height: 26px;">1091</span>) at java.util.AbstractList.listIterator(AbstractList.java:<span class="hljs-number" style="color: #1c00cf; line-height: 26px;">299</span>) at java.util.ArrayList$SubList.iterator(ArrayList.java:<span class="hljs-number" style="color: #1c00cf; line-height: 26px;">1087</span>) at java.util.AbstractCollection.toString(AbstractCollection.java:<span class="hljs-number" style="color: #1c00cf; line-height: 26px;">454</span>) at java.lang.String.valueOf(String.java:<span class="hljs-number" style="color: #1c00cf; line-height: 26px;">2994</span>) at java.lang.StringBuilder.append(StringBuilder.java:<span class="hljs-number" style="color: #1c00cf; line-height: 26px;">131</span>) </code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; color: black; margin: 10px 10px; line-height: 1.75; letter-spacing: 0.2em; font-size: 14px; word-spacing: 0.1em;">当我们对父元素 ArrayList 中对数据进行删除操作的时候,我们会发现 SubList 会报一个 ConcurrentModificationException 异常,这个异常是对数据比较发现元素被更改过,可以理解为脏数据吗?</p> <h2 data-tool="mdnice编辑器" style="margin-top: 40px; margin-bottom: 20px; font-weight: bold; color: black; font-size: 24px; text-align: left; margin: 20px 10px 0px 0px;"><span style="font-family: STHeitiSC-Light; font-size: 18px; font-weight: bolder; display: inline-block; padding-left: 10px; border-left: 5px solid rgb(248,57,41);">总结</span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; color: black; margin: 10px 10px; line-height: 1.75; letter-spacing: 0.2em; font-size: 14px; word-spacing: 0.1em;">1、 SubList 和 ArrayList 之间没有任何关系</p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; color: black; margin: 10px 10px; line-height: 1.75; letter-spacing: 0.2em; font-size: 14px; word-spacing: 0.1em;">2、千万不要将 SubList 转化为 ArrayList 会报转换异常</p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; color: black; margin: 10px 10px; line-height: 1.75; letter-spacing: 0.2em; font-size: 14px; word-spacing: 0.1em;">3、对 SubList 视图元素修改会影响原始父 ArrayList 中的数据。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; color: black; margin: 10px 10px; line-height: 1.75; letter-spacing: 0.2em; font-size: 14px; word-spacing: 0.1em;">4、对 ArrayList 数据删除添加等修改,SubList 会报 Modification 异常</p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; color: black; margin: 10px 10px; line-height: 1.75; letter-spacing: 0.2em; font-size: 14px; word-spacing: 0.1em;">其实我们可以理解下,SubList 理解为一个视图,其实就是一个内部类,它的实现就是在原始的 ArrayList 中改变了截取的索引位置。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; color: black; margin: 10px 10px; line-height: 1.75; letter-spacing: 0.2em; font-size: 14px; word-spacing: 0.1em;">对视图的操作结果会反映到原始的 ArrayList 中,如果对原始的 ArrayList 做数据的添加删除操作,不好意思此刻的 SubList 已经报异常了。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; color: black; margin: 10px 10px; line-height: 1.75; letter-spacing: 0.2em; font-size: 14px; word-spacing: 0.1em;">通俗一点,可以修改儿子,不能修改父亲。</p> <h2 data-tool="mdnice编辑器" style="margin-top: 40px; margin-bottom: 20px; font-weight: bold; color: black; font-size: 24px; text-align: left; margin: 20px 10px 0px 0px;"><span style="font-family: STHeitiSC-Light; font-size: 18px; font-weight: bolder; display: inline-block; padding-left: 10px; border-left: 5px solid rgb(248,57,41);">结果</span></h2> <h5 data-tool="mdnice编辑器" style="margin-top: 40px; margin-bottom: 20px; font-weight: bold; color: black; font-size: 16px;"><span>SubList 转化为 ArrayList 可以用 Guava 中的封装方法</span></h5> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; color: black; margin: 10px 10px; line-height: 1.75; letter-spacing: 0.2em; font-size: 14px; word-spacing: 0.1em;"><code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgb(271,93,108);">Lists.newArrayList(subList)</code></p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; color: black; margin: 10px 10px; line-height: 1.75; letter-spacing: 0.2em; font-size: 14px; word-spacing: 0.1em;">下次见!</p> </section>

原文出处:https://www.cnblogs.com/tonyY/p/12296344.html

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部