List接口做为Java集合框架中的一员,对数据的操作和处理比数组方便许多。在数组中插入一个元素要从数组的最后一个元素到当前插入的位置依次向后移动一位,然后为插入的位置进行赋值。在数组删除一个元素要从删除元素的下一个元素位置到数组最后一个元素依次向前移动一位。
今天学习python的时候看到
list = [1,1,1,2,3,4]
for i in range(len(list)):
if list[i] == 1:
del list[i]
这样是会报错的,然后我就想Java中的List如何删除重复的元素呢?于是做了一下尝试:
List<String> list = new ArrayList<String>();
list.add("a");
list.add("a");
list.add("a");
list.add("c");
//wrong way,每次删除index位置的元素,后边的index+1元素会向前移动到index的位置。下次遍历到Index+1实际上是index+2位置的元素,这样总会有一些元素没有办法遍历到。有一种解决方法是每删除一个元素,index--
for(int i=0;i<list.size();i++){
if(list.get(i).equals("a"))
list.remove(i);
}
//wrong way,这样操作会报错ConcurrentModificationException。此类的iterator和listIterator方法返回的迭代器是快速失败的:在创建迭代器之后,除非通过迭代器自身的remove或add方法从结构上对列表进行修改,否则在任何时间以任何方式对列表进行修改,迭代器都会抛出 ConcurrentModificationException。因此,面对并发的修改,迭代器很快就会完全失败,而不是冒着在将来某个不确定时间发生任意不确定行为的风险。
for(String li:list){
if(li.equals("a"))
list.remove(li);
}
//wrong way,创建迭代器之后,只能通过迭代器自身的remove或add方法从结构上对列表进行修改
Iterator it = list.iterator();
while(it.hasNext()){
String element = (String) it.next();
if(element.equals("a"))
list.remove(element);
}
//right,删除元素后下标会向前移动一个位置,所以由后向前删除就没有问题了。
for(int i=list.size()-1;i>-1;i--){
if(list.get(i).equals("a"))
list.remove(i);
}
//right,针对迭代器进行remove()也没有问题
Iterator iterator = list.iterator();
while(iterator.hasNext()){
if(iterator.next().equals("a"))
iterator.remove();
}
//right use set,一种最简单的方法是用set去除重复的元素。
Set<String> sets = new HashSet<String>();
sets.addAll(list);
System.err.println(sets);