集合遍歷過程中刪除集合元素問題
集合遍歷過程中如何刪除集合元素,,這個問題應該很簡單,用迭代器即可;
public static void main(String[] args) { List<String> strList = new ArrayList<String>(); strList.add("aa"); strList.add("bb"); strList.add("cc"); System.out.println(strList); Iterator<String> it = strList.iterator(); while (it.hasNext()) { String str = it.next(); if ("bb".equals(str)) { it.remove(); } } System.out.println(strList); }
列印結果:
[aa, bb, cc]
[aa, cc]
對於上面這個問題就不多做贅述了;
來看下面的程式碼:
列印結果:public static void main(String[] args) { List<String> strList = Arrays.asList("aa", "bb", "cc"); System.out.println(strList); Iterator<String> it = strList.iterator(); while (it.hasNext()) { String str = it.next(); if ("bb".equals(str)) { it.remove(); } } System.out.println(strList); }
Exception in thread "main" java.lang.UnsupportedOperationException
[aa, bb, cc]
at java.util.AbstractList.remove(AbstractList.java:161)
at java.util.AbstractList$Itr.remove(AbstractList.java:374)
at Collection.ListTest.main(ListTest.java:30)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
這個是之前碰到的問題,,當時沒怎麼注意,換了種實現方式就沒管了;
為什麼會出現這種狀況呢?去仔細翻了下原始碼就理解了;
看Arrays原始碼得知
List<String> strList = Arrays.asList("aa", "bb", "cc");
這裡的strList物件不是我們常用的java.util.ArrayList的例項物件,而是Arrays的靜態內部類ArrayList的例項物件;
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
/**
* @serial include
*/
private static class ArrayList<E> extends AbstractList<E>
implements RandomAccess, java.io.Serializable
{
private static final long serialVersionUID = -2764017481108945198L;
private final E[] a;
ArrayList(E[] array) {
a = Objects.requireNonNull(array);
}
@Override
public int size() {
return a.length;
}
@Override
public Object[] toArray() {
return a.clone();
}
@Override
@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a) {
int size = size();
if (a.length < size)
return Arrays.copyOf(this.a, size,
(Class<? extends T[]>) a.getClass());
System.arraycopy(this.a, 0, a, 0, size);
if (a.length > size)
a[size] = null;
return a;
}
@Override
public E get(int index) {
return a[index];
}
@Override
public E set(int index, E element) {
E oldValue = a[index];
a[index] = element;
return oldValue;
}
@Override
public int indexOf(Object o) {
E[] a = this.a;
if (o == null) {
for (int i = 0; i < a.length; i++)
if (a[i] == null)
return i;
} else {
for (int i = 0; i < a.length; i++)
if (o.equals(a[i]))
return i;
}
return -1;
}
@Override
public boolean contains(Object o) {
return indexOf(o) != -1;
}
@Override
public Spliterator<E> spliterator() {
return Spliterators.spliterator(a, Spliterator.ORDERED);
}
@Override
public void forEach(Consumer<? super E> action) {
Objects.requireNonNull(action);
for (E e : a) {
action.accept(e);
}
}
@Override
public void replaceAll(UnaryOperator<E> operator) {
Objects.requireNonNull(operator);
E[] a = this.a;
for (int i = 0; i < a.length; i++) {
a[i] = operator.apply(a[i]);
}
}
@Override
public void sort(Comparator<? super E> c) {
Arrays.sort(a, c);
}
}
看原始碼得知,,這裡的ArrayList(Arrays的靜態內部類)沒有覆蓋/重寫java.util.AbstractList的iterator()方法,,所以呼叫的是AbstractList的iterator()方法;
接下來看一看java.util.AbstractList的部分對應原始碼:
public Iterator<E> iterator() {
return new Itr();
}
private class Itr implements Iterator<E> {
/**
* Index of element to be returned by subsequent call to next.
*/
int cursor = 0;
/**
* Index of element returned by most recent call to next or
* previous. Reset to -1 if this element is deleted by a call
* to remove.
*/
int lastRet = -1;
/**
* The modCount value that the iterator believes that the backing
* List should have. If this expectation is violated, the iterator
* has detected concurrent modification.
*/
int expectedModCount = modCount;
public boolean hasNext() {
return cursor != size();
}
public E next() {
checkForComodification();
try {
int i = cursor;
E next = get(i);
lastRet = i;
cursor = i + 1;
return next;
} catch (IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
}
}
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
AbstractList.this.remove(lastRet);
if (lastRet < cursor)
cursor--;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException e) {
throw new ConcurrentModificationException();
}
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
看到這裡,Arrays的靜態內部類ArrayList的例項物件strList呼叫iterator()生成的物件,實際上是這裡Itr的物件例項;
故執行報錯程式碼while迴圈中呼叫的remove()方法也是Itr的remove()方法,而由上面的程式碼可以發現,這裡remove的實現靠的是
AbstractList.this.remove(lastRet);
即呼叫的是AbstractList本身的remove()方法,再去看AbstractList的原始碼;
/**
* {@inheritDoc}
*
* <p>This implementation always throws an
* {@code UnsupportedOperationException}.
*
* @throws UnsupportedOperationException {@inheritDoc}
* @throws ClassCastException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
* @throws IllegalArgumentException {@inheritDoc}
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public E set(int index, E element) {
throw new UnsupportedOperationException();
}
/**
* {@inheritDoc}
*
* <p>This implementation always throws an
* {@code UnsupportedOperationException}.
*
* @throws UnsupportedOperationException {@inheritDoc}
* @throws ClassCastException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
* @throws IllegalArgumentException {@inheritDoc}
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public void add(int index, E element) {
throw new UnsupportedOperationException();
}
/**
* {@inheritDoc}
*
* <p>This implementation always throws an
* {@code UnsupportedOperationException}.
*
* @throws UnsupportedOperationException {@inheritDoc}
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public E remove(int index) {
throw new UnsupportedOperationException();
}
可以看到AbstractList中並沒有實現對應的set、add、remove方法,而是直接丟擲了UnsupportedOperationException異常,這個與之前打印出來的輸出結果吻合;
最後再來看看java.util.Arrays$ArrayList的原始碼;
雖然繼承了java.util.AbstractList抽象類,但是並沒有重寫其add、remove等方法,只能做一些簡單的取值遍歷操作;
private static class ArrayList<E> extends AbstractList<E>
implements RandomAccess, java.io.Serializable
{
private static final long serialVersionUID = -2764017481108945198L;
private final E[] a;
ArrayList(E[] array) {
a = Objects.requireNonNull(array);
}
@Override
public int size() {
return a.length;
}
@Override
public Object[] toArray() {
return a.clone();
}
@Override
@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a) {
int size = size();
if (a.length < size)
return Arrays.copyOf(this.a, size,
(Class<? extends T[]>) a.getClass());
System.arraycopy(this.a, 0, a, 0, size);
if (a.length > size)
a[size] = null;
return a;
}
@Override
public E get(int index) {
return a[index];
}
@Override
public E set(int index, E element) {
E oldValue = a[index];
a[index] = element;
return oldValue;
}
@Override
public int indexOf(Object o) {
E[] a = this.a;
if (o == null) {
for (int i = 0; i < a.length; i++)
if (a[i] == null)
return i;
} else {
for (int i = 0; i < a.length; i++)
if (o.equals(a[i]))
return i;
}
return -1;
}
@Override
public boolean contains(Object o) {
return indexOf(o) != -1;
}
@Override
public Spliterator<E> spliterator() {
return Spliterators.spliterator(a, Spliterator.ORDERED);
}
@Override
public void forEach(Consumer<? super E> action) {
Objects.requireNonNull(action);
for (E e : a) {
action.accept(e);
}
}
@Override
public void replaceAll(UnaryOperator<E> operator) {
Objects.requireNonNull(operator);
E[] a = this.a;
for (int i = 0; i < a.length; i++) {
a[i] = operator.apply(a[i]);
}
}
@Override
public void sort(Comparator<? super E> c) {
Arrays.sort(a, c);
}
}
相關推薦
集合遍歷過程中刪除集合元素問題
集合遍歷過程中如何刪除集合元素,,這個問題應該很簡單,用迭代器即可; public static void main(String[] args) { List<String> strList = new ArrayList<String
Java_遍歷集合過程中刪除集合元素報錯的解決方案
問題描述:使用增強for迴圈遍歷集合,如果遍歷過程中去除第一個或者最後一個元素會報錯,去除中間的元素不會報錯:Exception in thread “main” java.util.ConcurrentModificationException 不知道這個是
集合遍歷過程iterator, 添加刪除元素報異常
exc asn 一致性 使用 遍歷 one mov exceptio 刪除 list set 遍歷過程中添加或者刪除元素,報異常。 使用iterator 也會報異常 ConcurrentModificationException remove只能用叠代器的remov
如何正確在集合遍歷的時候刪除多個元素
前言 不管是集合中的遍歷還是刪除集合中元素,這些操作相比大家都很熟悉,但是在日常開發中,我們有時候會遇到在集合遍歷的時候刪除集合中的元素。那麼這裡面有什麼哪些小竅門呢?為什麼標題上說是刪除多個元素,難倒刪除多個元素和刪除單個元素有什麼區別? 常見的for
Map集合遍歷過程呼叫remove方法引起的問題
Set<Integer> set2 = map2.keySet(); for(Integer key :set2) { if(key>50 && key<1
C#遍歷List並刪除某個元素的方法
ffffff nbsp 句柄 實現 padding 分析 win html round 本文實例分析了C#遍歷List並刪除某個元素的方法。分享給大家供大家參考。具體如下: 1、我們選擇用for循環:for(int i=0;i<list.count;i++) {
list在遍歷過程中的add/remove
com index 遍歷集合 很多 pub iterator clas util http 平時開發過程中,很多人估計都遇到過一個問題:在遍歷集合的的過程中,進行add或者remove操作的時候,會出現2類錯誤,包括:java.util.ConcurrentModifica
python 遍歷list並刪除部分元素
python 遍歷list並刪除部分元素 有兩個list,list_1 為0-9,list_2 為0-4,需要刪除list_1中包含在list_2中的元素 list_1 =[] for i in range(10): list_1.append(str(i)) list
初學者在python遍歷序列同時刪除相鄰元素時的易錯點
(1)問題的案例 以列表List為例 現在有一個列表,我想要遍歷它,然後判斷每個元素是否滿足某個條件而需要被刪除,如下面一段程式碼: test = [11,22,33,44,55,66] for temp in test: if temp == 22 or t
如何實現在遍歷集合的過程中刪除其中的元素
為了進行測試,下面是取自MatLab中的一段小程式,其中第2行是計算集合的長度,第三行是從後往前遍歷集合的MatLab專用語法,第5行是刪除第j個元素。 function res = testDel
java集合遍歷刪除指定元素異常分析總結
它的 一次 但是 代碼 元素 拋出異常 源碼 刪除指定元素 test 在使用集合的過程中,我們經常會有遍歷集合元素,刪除指定的元素的需求,而對於這種需求我們往往使用會犯些小錯誤,導致程序拋異常或者與預期結果不對,本人很早之前就遇到過這個坑,當時沒註意總結,結果前段時間又遇到
集合遍歷中刪除行不行
package 演算法; import java.util.ArrayList; import java.util.List; public class 集合遍歷中刪除行不行 { /** * 面試中會問到lis
Java中List集合遍歷的三種方式
asn tex iter for nbsp next next() ray string 首先創建一個List集合: List<String> list = new ArrayList<String>();list.add("name"); list
Java中的Map集合以及Map集合遍歷例項
文章目錄 一、Map集合 二、Map集合遍歷例項 一、Map集合 Map<K,V>k是鍵,v是值 1、 將鍵對映到值的物件,一
java集合遍歷中的向下轉型、泛型
java中集合儲存字串時,集合的get(i)方法是獲取集合中的第i+1個元素,而這個元素是Object型別,而Object型別沒有length()方法,遍歷的時候如果直接.length()會報錯。如果想使用字串的方法,就必須把元素還原成字元(向下轉型)。 集合的遍歷。其實就是依次獲取集合
實際開發中,解決列印iReport中獲取list集合遍歷,並且縮小間距
用iReport做列印的時候,在後端程式碼中得到map集合後,map中存放list 用$F獲取屬性,欄屬性代表每行的空、間隔 /*** * * @author xxx * @param checkVisaReqVo *
將一個集合類的某一欄位遍歷到另一個集合中
我們在開發中經常會遇到這種情況,就是在查詢一個列表的時候,可能會需要將另一個表中的某些欄位拼接到這一個列表中,在這種時候,如果是取到列表之後,然後根據某一個欄位再去一個一個的查詢的話,就會很費資源,介面也會變的很慢。 &nbs
mybatis的配置檔案中使用兩個或多個foreach進行多個集合遍歷的問題
<select id="selectTrafficEventIngByType" resultMap="BaseResultMap"> select <include refid="Base_Column_List"/> f
迭代器迭代元素,迭代器修改元素;集合集合遍歷元素集合修改元素解決併發修改異常
import java.util.ArrayList;import java.util.List;import java.util.ListIterator;public class TextDemo1
javascript中遍歷EL表示式List集合中的值
今天遇到個問題就是我想在js中獲取後臺傳來的list中的值。本來頁面展現是用的EL表示式,一切都沒有什麼問題,但是我要動態獲取集合中的url然後在js中呼叫qrcode生成二維碼,當我嘗試按大部分的思