java关于list集合做删除操作时的坑及解决
关于list集合做删除操作时的坑
一个arraylist在做删除操作时,如果你使用如下方式,会有什么问题?
import java.util.arraylist; import java.util.list; public class deletelist { public static void main(string[] args) { list<integer> list = new arraylist<integer>(); list.add(1); list.add(2); list.add(3); list.add(3); list.add(3); list.add(4); for(int i=0;i<list.size();i++){ if (list.get(i)==3) { list.remove(i); } } system.out.println(list); } }
结果:[1, 2, 3, 4]。
分析问题:为什么会是有一个3遗留了?因为在访问到list[2]时,满足等于3,进行删除。此时,3后面的元素会向左移动一位,也就是第二个3进入到i=2处,然后i=3,删除第三个3,这样就会漏掉第二个3.
解决办法
1、访问list从后往前,从i=size-1至i=0,可以避免上述问题;
2、使用iterator迭代器。
iterator it = list.iterator(); while (it.hasnext()) { integer p = (integer) it.next(); if(p==3){ it.remove(); } } system.out.println(list);
结果:[1, 2, 4]
下面是迭代器的部分源码:当执行remove方法时,将当前位置赋值给游标cursor,再进行next时,还是获取当前位置的元素,也就是下一个位置移动过来的元素。这样就避免的遗漏元素。关键点是删除时,当前位置是i,游标的位置是i+1,修改游标的位置为i。
public e next() { checkforcomodification(); int i = cursor; if (i >= size) throw new nosuchelementexception(); object[] elementdata = arraylist.this.elementdata; if (i >= elementdata.length) throw new concurrentmodificationexception(); cursor = i + 1; return (e) elementdata[lastret = i]; } public void remove() { if (lastret < 0) throw new illegalstateexception(); checkforcomodification(); try { arraylist.this.remove(lastret); cursor = lastret; lastret = -1; expectedmodcount = modcount; } catch (indexoutofboundsexception ex) { throw new concurrentmodificationexception(); } }
对list集合的常用操作
备注:内容中代码具有关联性。
1.list中添加,获取,删除元素
添加方法是:.add(e)
获取方法是:.get(index)
删除方法是:.remove(index)
按照索引删除;.remove(object o)
按照元素内容删除;
list<string> person=new arraylist<>(); person.add("jackie"); //索引为0 //.add(e) person.add("peter"); //索引为1 person.add("annie"); //索引为2 person.add("martin"); //索引为3 person.add("marry"); //索引为4 person.remove(3); //.remove(index) person.remove("marry"); //.remove(object o) string per=""; per=person.get(1); system.out.println(per); ////.get(index) for (int i = 0; i < person.size(); i++) { system.out.println(person.get(i)); //.get(index) }
2.list中是否包含某个元素
方法:.contains(object o); 返回true或者false
list<string> fruits=new arraylist<>(); fruits.add("苹果"); fruits.add("香蕉"); fruits.add("桃子"); //for循环遍历list for (int i = 0; i < fruits.size(); i++) { system.out.println(fruits.get(i)); } string applestring="苹果"; //true or false system.out.println("fruits中是否包含苹果:"+fruits.contains(applestring)); if (fruits.contains(applestring)) { system.out.println("我喜欢吃苹果"); }else { system.out.println("我不开心"); }
3.list中根据索引将元素数值改变(替换)
注意 .set(index, element); 和 .add(index, element); 的不同;
string a="白龙马", b="沙和尚", c="八戒", d="唐僧", e="悟空"; list<string> people=new arraylist<>(); people.add(a); people.add(b); people.add(c); people.set(0, d); //.set(index, element); //将d唐僧放到list中索引为0的位置,替换a白龙马 people.add(1, e); //.add(index, element); //将e悟空放到list中索引为1的位置,原来位置的b沙和尚后移一位 //增强for循环遍历list for(string str:people){ system.out.println(str); }
4.list中查看(判断)元素的索引
注意:.indexof(); 和 lastindexof()的不同;
list<string> names=new arraylist<>(); names.add("刘备"); //索引为0 names.add("关羽"); //索引为1 names.add("张飞"); //索引为2 names.add("刘备"); //索引为3 names.add("张飞"); //索引为4 system.out.println(names.indexof("刘备")); system.out.println(names.lastindexof("刘备")); system.out.println(names.indexof("张飞")); system.out.println(names.lastindexof("张飞"));
5.根据元素索引位置进行的判断
if (names.indexof("刘备")==0) { system.out.println("刘备在这里"); }else if (names.lastindexof("刘备")==3) { system.out.println("刘备在那里"); }else { system.out.println("刘备到底在哪里?"); }
6.利用list中索引位置重新生成一个新的list(截取集合)
方法:
.sublist(fromindex, toindex)
.size()
该方法得到list中的元素数的和
list<string> phone=new arraylist<>(); phone.add("三星"); //索引为0 phone.add("苹果"); //索引为1 phone.add("锤子"); //索引为2 phone.add("华为"); //索引为3 phone.add("小米"); //索引为4 //原list进行遍历 for(string pho:phone){ system.out.println(pho); } //生成新list phone=phone.sublist(1, 4); //.sublist(fromindex, toindex) //利用索引1-4的对象重新生成一个list,但是不包含索引为4的元素,4-1=3 for (int i = 0; i < phone.size(); i++) { // phone.size() 该方法得到list中的元素数的和 system.out.println("新的list包含的元素是"+phone.get(i)); }
7.对比两个list中的所有元素
两个相等对象的equals方法一定为true, 但两个hashcode相等的对象不一定是相等的对象
//1.<br>if (person.equals(fruits)) { system.out.println("两个list中的所有元素相同"); }else { system.out.println("两个list中的所有元素不一样"); } //2. if (person.hashcode()==fruits.hashcode()) { system.out.println("我们相同"); }else { system.out.println("我们不一样"); }
8.判断list是否为空
//空则返回true,非空则返回false
if (person.isempty()) { system.out.println("空的"); }else { system.out.println("不是空的"); }
9.返回iterator集合对象
system.out.println("返回iterator集合对象:"+person.iterator());
10.将集合转换为字符串
string listring=""; listring=person.tostring(); system.out.println("将集合转换为字符串:"+listring);
11.将集合转换为数组
system.out.println("将集合转换为数组:"+person.toarray());
12.集合类型转换
//1.默认类型 list<object> listsstrings=new arraylist<>(); for (int i = 0; i < person.size(); i++) { listsstrings.add(person.get(i)); } //2.指定类型 list<stringbuffer> lst=new arraylist<>(); for(string string:person){ lst.add(stringbuffer(string)); }
13.去重复
list<string> lst1=new arraylist<>(); lst1.add("aa"); lst1.add("dd"); lst1.add("ss"); lst1.add("aa"); lst1.add("ss"); //方法 1. for (int i = 0; i <lst1.size()-1; i++) { for (int j = lst1.size()-1; j >i; j--) { if (lst1.get(j).equals(lst1.get(i))) { lst1.remove(j); } } } system.out.println(lst1); //方法 2. list<string> lst2=new arraylist<>(); for (string s:lst1) { if (collections.frequency(lst2, s)<1) { lst2.add(s); } } system.out.println(lst2);
附完整代码:
package mytest01; import java.util.arraylist; import java.util.list; public class listtest01 { public static void main(string[] args) { //list中添加,获取,删除元素 list<string> person=new arraylist<>(); person.add("jackie"); //索引为0 //.add(e) person.add("peter"); //索引为1 person.add("annie"); //索引为2 person.add("martin"); //索引为3 person.add("marry"); //索引为4 person.remove(3); //.remove(index) person.remove("marry"); //.remove(object o) string per=""; per=person.get(1); system.out.println(per); ////.get(index) for (int i = 0; i < person.size(); i++) { system.out.println(person.get(i)); //.get(index) } //list总是否包含某个元素 list<string> fruits=new arraylist<>(); fruits.add("苹果"); fruits.add("香蕉"); fruits.add("桃子"); //for循环遍历list for (int i = 0; i < fruits.size(); i++) { system.out.println(fruits.get(i)); } string applestring="苹果"; //true or false system.out.println("fruits中是否包含苹果:"+fruits.contains(applestring)); if (fruits.contains(applestring)) { system.out.println("我喜欢吃苹果"); }else { system.out.println("我不开心"); } //list中根据索引将元素数值改变(替换) string a="白龙马", b="沙和尚", c="八戒", d="唐僧", e="悟空"; list<string> people=new arraylist<>(); people.add(a); people.add(b); people.add(c); people.set(0, d); //.set(index, element) //将d唐僧放到list中索引为0的位置,替换a白龙马 people.add(1, e); //.add(index, element); //将e悟空放到list中索引为1的位置,原来位置的b沙和尚后移一位 //增强for循环遍历list for(string str:people){ system.out.println(str); } //list中查看(判断)元素的索引 list<string> names=new arraylist<>(); names.add("刘备"); //索引为0 names.add("关羽"); //索引为1 names.add("张飞"); //索引为2 names.add("刘备"); //索引为3 names.add("张飞"); //索引为4 system.out.println(names.indexof("刘备")); system.out.println(names.lastindexof("刘备")); system.out.println(names.indexof("张飞")); system.out.println(names.lastindexof("张飞")); //根据元素索引位置进行的判断 if (names.indexof("刘备")==0) { system.out.println("刘备在这里"); }else if (names.lastindexof("刘备")==3) { system.out.println("刘备在那里"); }else { system.out.println("刘备到底在哪里?"); } //利用list中索引位置重新生成一个新的list(截取集合) list<string> phone=new arraylist<>(); phone.add("三星"); //索引为0 phone.add("苹果"); //索引为1 phone.add("锤子"); //索引为2 phone.add("华为"); //索引为3 phone.add("小米"); //索引为4 //原list进行遍历 for(string pho:phone){ system.out.println(pho); } //生成新list phone=phone.sublist(1, 4); //.sublist(fromindex, toindex) //利用索引1-4的对象重新生成一个list,但是不包含索引为4的元素,4-1=3 for (int i = 0; i < phone.size(); i++) { // phone.size() 该方法得到list中的元素数的和 system.out.println("新的list包含的元素是"+phone.get(i)); } //对比两个list中的所有元素 //两个相等对象的equals方法一定为true, 但两个hashcode相等的对象不一定是相等的对象 if (person.equals(fruits)) { system.out.println("两个list中的所有元素相同"); }else { system.out.println("两个list中的所有元素不一样"); } if (person.hashcode()==fruits.hashcode()) { system.out.println("我们相同"); }else { system.out.println("我们不一样"); } //判断list是否为空 //空则返回true,非空则返回false if (person.isempty()) { system.out.println("空的"); }else { system.out.println("不是空的"); } //返回iterator集合对象 system.out.println("返回iterator集合对象:"+person.iterator()); //将集合转换为字符串 string listring=""; listring=person.tostring(); system.out.println("将集合转换为字符串:"+listring); //将集合转换为数组,默认类型 system.out.println("将集合转换为数组:"+person.toarray()); ////将集合转换为指定类型(友好的处理) //1.默认类型 list<object> listsstrings=new arraylist<>(); for (int i = 0; i < person.size(); i++) { listsstrings.add(person.get(i)); } //2.指定类型 list<stringbuffer> lst=new arraylist<>(); for(string string:person){ lst.add(stringbuffer(string)); } } private static stringbuffer stringbuffer(string string) { return null; } }
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。
上一篇: Vue中的computed属性详解
下一篇: 软件设计七大原则