关于LinkedList的删除问题

平菇虾饺 2013-12-03 01:40:30
我最近写了一个测试程序,是这样的:
①新建一个测试List,往里面添加很多的元素。
②再根据元素类别删掉不想要的元素。
③打印出list

这里面出现了一个问题:元素无法被删除完整!

请各位指教!
MODEL:
public class AreaTerminalFinalModel {

private Integer mark;
private String levelMark;
private Double label;
private boolean check;
//构造器
public AreaTerminalFinalModel(Integer mark, String levelMark, Float label) {
//name 为 区域/品牌 名 ,
this.mark = mark;
this.levelMark = levelMark;
String a = String.valueOf(label);
BigDecimal bd = new BigDecimal(a);
this.label = bd.doubleValue();
this.setCheck(false);
}
public boolean levelSame(AreaTerminalFinalModel a) {
return this.getLevelMark().equals(a.getLevelMark());
}
}


这是我的测试代码:

package sn.utils;

import java.util.LinkedList;
import java.util.List;

import sn.model.AreaTerminalFinalModel;

public class TestList {
public static void main(String[] args) {
List<AreaTerminalFinalModel> list
= new LinkedList<AreaTerminalFinalModel>();
String[] name = {"标准C1","正规工具","测试代码","实验室","公关系统","航空交通","河流","道路","一心一意","PIC","无良商家","happy",};
Float[] num = {0.35f , 4f ,1.1f , 726f , 2.8f , 0f , -12f , 23f , 9f};
for (int i = 0 ; i < 36 ; i ++) {
list.add(new AreaTerminalFinalModel((int)(Math.random()*10),
name[(int)(Math.random()*12)],
num[(int)(Math.random()*num.length)]));
}
for (int i = 0 ; i < list.size() ; i ++) {
for (int j = i+1 ; j < list.size() ; j ++) {
if(list.get(i).getMark().intValue() ==
list.get(j).getMark().intValue()
&& list.get(i).levelSame(list.get(j)))
{
Double a = (list.get(i).getLabel()==null && !list.get(i).isCheck())?0.0:list.get(i).getLabel();
Double b = (list.get(j).getLabel()==null && !list.get(j).isCheck())?0.0:list.get(j).getLabel();
list.get(i).setLabel(a+b);
list.get(j).setCheck(true);
}
}
}
synchronized (list) {
for (int i = 0 ; i < list.size() ; i ++) {
if(list.get(i).isCheck()) {
list.remove(i);
}
}
}
for (int i = 0 ; i <list.size() ; i++) {
System.out.println(list.get(i).getMark()
+"---\t"+list.get(i).getLevelMark()
+"---\t"+list.get(i).isCheck());
}
}

}


预期输出中本不应该出现 true的,但是它确确实实出现了,我不是太会synchronized的用法,所以大神见怪请轻拍。
预期输出:
...
..
.4--- happy--- false
1--- 无良商家--- false
5--- 正规工具--- false
2--- 公关系统--- false
0--- 道路--- false
7--- happy--- false
1--- 道路--- false
8--- 一心一意--- false
3--- 道路--- false
8--- happy--- false
6--- PIC--- false
3--- 无良商家--- false
7--- 测试代码--- false
3--- PIC--- false
0--- 一心一意--- false
0--- happy--- false

实际输出:
...
..
.
0--- 标准C1--- true
.
..
...
请指教!
...全文
352 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
fuzeqiang 2013-12-03
  • 打赏
  • 举报
回复
两个问题:在循环删除的时候,你的控制变量i应该初始化为集合长度,否则你连遍历都没有完全完成,还删个毛线。还有一些集合在迭代的时候是不能进行删除操作的,你可以把需要删除的元素用另外一个集合记录,在迭代完成后再删除记录的元素。
平菇虾饺 2013-12-03
  • 打赏
  • 举报
回复
引用 11 楼 ganshenml 的回复:
[quote=引用 9 楼 qyp199312 的回复:] [quote=引用 8 楼 ganshenml 的回复:] [quote=引用 5 楼 qyp199312 的回复:] [quote=引用 3 楼 ganshenml 的回复:] 把list放进迭代器中,利用这个迭代器遍历到你需要对应的数据处然后调用迭代器对象的删除方法!
可是我还是没有明白元素没有被删除的原因,,,[/quote]把同步synchronized这条语句去掉,关掉编辑器,隔几分钟之后再看,然后运行看看![/quote] 我昨晚到现在都关机了,,我是用迭代器删除的,我也debug了一下。但是我还是没有明白为什么没有删除掉它[/quote]同步块,资源被占用,而for循环里面继续操作,当资源被释放,下一个对象被同步的时候,到这里已经走了几个对象了,所谓的漏网之鱼吧!纯属猜测!家无水表,请勿跨省![/quote] 大概说法和你那个一样,但是意思不同了。 这与同步锁没有关系的,操作方永远只有进程本身。 在remove的时候后一元素在删除时立马前移,而后才执行i++动作,因此后面那个相当于是被漏掉了。是这样的
平菇虾饺 2013-12-03
  • 打赏
  • 举报
回复
引用 10 楼 qyp199312 的回复:
[quote=引用 7 楼 jackwumengfeng 的回复:] 直接在for循环中删除元素肯定是不行的,给你个实例看看这样删除后的结果:
public static void main(String[] args) {
		List<AreaTerminalFinalModel> list
		= new LinkedList<AreaTerminalFinalModel>();
		list.add(new AreaTerminalFinalModel(1, "标准C1", 1f));
		list.add(new AreaTerminalFinalModel(2, "实验室", 2f));
		list.add(new AreaTerminalFinalModel(3, "公关系统", 3f));
		list.add(new AreaTerminalFinalModel(4, "航空交通", 4f));
		list.add(new AreaTerminalFinalModel(5, "标准C1", 5f));
		list.add(new AreaTerminalFinalModel(6, "标准C1", 6f));
		
		System.out.println("删除前:");
		for (int i = 0 ; i <list.size() ; i++) {
			System.out.println(list.get(i).getMark()
					+"---\t"+list.get(i).getLevelMark()
					+"---\t"+list.get(i).getLabel());
		}
		
		for (int i = 0 ; i < list.size() ; i ++) {
			//删除levelMark为"标准C1"的元素
			if(list.get(i).getLevelMark().equals("标准C1")) {
				list.remove(i);
			}
		}
		
		
		System.out.println("删除后:");
		for (int i = 0 ; i <list.size() ; i++) {
			System.out.println(list.get(i).getMark()
					+"---\t"+list.get(i).getLevelMark()
					+"---\t"+list.get(i).getLabel());
		}
	}
我用迭代器删除成功了,,,但是for循环里面,,,我再debug一次试试[/quote] 我找到原因了,,谢了!
ganshenml 2013-12-03
  • 打赏
  • 举报
回复
引用 9 楼 qyp199312 的回复:
[quote=引用 8 楼 ganshenml 的回复:] [quote=引用 5 楼 qyp199312 的回复:] [quote=引用 3 楼 ganshenml 的回复:] 把list放进迭代器中,利用这个迭代器遍历到你需要对应的数据处然后调用迭代器对象的删除方法!
可是我还是没有明白元素没有被删除的原因,,,[/quote]把同步synchronized这条语句去掉,关掉编辑器,隔几分钟之后再看,然后运行看看![/quote] 我昨晚到现在都关机了,,我是用迭代器删除的,我也debug了一下。但是我还是没有明白为什么没有删除掉它[/quote]同步块,资源被占用,而for循环里面继续操作,当资源被释放,下一个对象被同步的时候,到这里已经走了几个对象了,所谓的漏网之鱼吧!纯属猜测!家无水表,请勿跨省!
平菇虾饺 2013-12-03
  • 打赏
  • 举报
回复
引用 7 楼 jackwumengfeng 的回复:
直接在for循环中删除元素肯定是不行的,给你个实例看看这样删除后的结果:
public static void main(String[] args) {
		List<AreaTerminalFinalModel> list
		= new LinkedList<AreaTerminalFinalModel>();
		list.add(new AreaTerminalFinalModel(1, "标准C1", 1f));
		list.add(new AreaTerminalFinalModel(2, "实验室", 2f));
		list.add(new AreaTerminalFinalModel(3, "公关系统", 3f));
		list.add(new AreaTerminalFinalModel(4, "航空交通", 4f));
		list.add(new AreaTerminalFinalModel(5, "标准C1", 5f));
		list.add(new AreaTerminalFinalModel(6, "标准C1", 6f));
		
		System.out.println("删除前:");
		for (int i = 0 ; i <list.size() ; i++) {
			System.out.println(list.get(i).getMark()
					+"---\t"+list.get(i).getLevelMark()
					+"---\t"+list.get(i).getLabel());
		}
		
		for (int i = 0 ; i < list.size() ; i ++) {
			//删除levelMark为"标准C1"的元素
			if(list.get(i).getLevelMark().equals("标准C1")) {
				list.remove(i);
			}
		}
		
		
		System.out.println("删除后:");
		for (int i = 0 ; i <list.size() ; i++) {
			System.out.println(list.get(i).getMark()
					+"---\t"+list.get(i).getLevelMark()
					+"---\t"+list.get(i).getLabel());
		}
	}
我用迭代器删除成功了,,,但是for循环里面,,,我再debug一次试试
平菇虾饺 2013-12-03
  • 打赏
  • 举报
回复
引用 8 楼 ganshenml 的回复:
[quote=引用 5 楼 qyp199312 的回复:] [quote=引用 3 楼 ganshenml 的回复:] 把list放进迭代器中,利用这个迭代器遍历到你需要对应的数据处然后调用迭代器对象的删除方法!
可是我还是没有明白元素没有被删除的原因,,,[/quote]把同步synchronized这条语句去掉,关掉编辑器,隔几分钟之后再看,然后运行看看![/quote] 我昨晚到现在都关机了,,我是用迭代器删除的,我也debug了一下。但是我还是没有明白为什么没有删除掉它
ganshenml 2013-12-03
  • 打赏
  • 举报
回复
引用 5 楼 qyp199312 的回复:
[quote=引用 3 楼 ganshenml 的回复:] 把list放进迭代器中,利用这个迭代器遍历到你需要对应的数据处然后调用迭代器对象的删除方法!
可是我还是没有明白元素没有被删除的原因,,,[/quote]把同步synchronized这条语句去掉,关掉编辑器,隔几分钟之后再看,然后运行看看!
南猿北蛰 2013-12-03
  • 打赏
  • 举报
回复
直接在for循环中删除元素肯定是不行的,给你个实例看看这样删除后的结果:
public static void main(String[] args) {
		List<AreaTerminalFinalModel> list
		= new LinkedList<AreaTerminalFinalModel>();
		list.add(new AreaTerminalFinalModel(1, "标准C1", 1f));
		list.add(new AreaTerminalFinalModel(2, "实验室", 2f));
		list.add(new AreaTerminalFinalModel(3, "公关系统", 3f));
		list.add(new AreaTerminalFinalModel(4, "航空交通", 4f));
		list.add(new AreaTerminalFinalModel(5, "标准C1", 5f));
		list.add(new AreaTerminalFinalModel(6, "标准C1", 6f));
		
		System.out.println("删除前:");
		for (int i = 0 ; i <list.size() ; i++) {
			System.out.println(list.get(i).getMark()
					+"---\t"+list.get(i).getLevelMark()
					+"---\t"+list.get(i).getLabel());
		}
		
		for (int i = 0 ; i < list.size() ; i ++) {
			//删除levelMark为"标准C1"的元素
			if(list.get(i).getLevelMark().equals("标准C1")) {
				list.remove(i);
			}
		}
		
		
		System.out.println("删除后:");
		for (int i = 0 ; i <list.size() ; i++) {
			System.out.println(list.get(i).getMark()
					+"---\t"+list.get(i).getLevelMark()
					+"---\t"+list.get(i).getLabel());
		}
	}
平菇虾饺 2013-12-03
  • 打赏
  • 举报
回复
你们看我测试了这个方法:
		synchronized (list) {
			
			for (int i = 0 ; i < list.size() ; i ++) {
				System.out.println(list.get(i).getMark()
						+"---\t"+list.get(i).getLevelMark()
						+"---\t"+list.get(i).isCheck());
				if(list.get(i).isCheck()) {
					System.out.println("删除-----------"+list.remove(i));
					
				}
			}
		}
得出的结论是; 8--- 正规工具--- false 0--- 无良商家--- false 8--- PIC管道--- false 1--- happyeve--- false 3--- PIC管道--- false 2--- 测试代码--- false 6--- 河流航海--- false 4--- 测试代码--- false 5--- 道路运营--- false 5--- 测试代码--- false 1--- 实验室jia--- false 4--- 实验室jia--- false 5--- 测试代码--- true 删除-----------sn.model.AreaTerminalFinalModel@79fc7299 4--- 无良商家--- false 7--- 河流航海--- false 6--- 航空交通--- false 3--- 测试代码--- false 4--- 测试代码--- true 删除-----------sn.model.AreaTerminalFinalModel@2cc7d960 3--- 河流航海--- false 5--- happyeve--- false 9--- 一心一意--- false 7--- 标准C1TTTT--- false 4--- 一心一意--- false 7--- 道路运营--- true 删除-----------sn.model.AreaTerminalFinalModel@74904497 7--- 无良商家--- false 6--- 河流航海--- true 删除-----------sn.model.AreaTerminalFinalModel@2b87514a 8--- 无良商家--- false 5--- 公关系统--- false 2--- 正规工具--- false 3--- PIC管道--- true 删除-----------sn.model.AreaTerminalFinalModel@40e9e799 3--- 无良商家--- false 每一个找到的元素都是执行了删除方法的。可是为什么就是删不掉呢????
平菇虾饺 2013-12-03
  • 打赏
  • 举报
回复
引用 3 楼 ganshenml 的回复:
把list放进迭代器中,利用这个迭代器遍历到你需要对应的数据处然后调用迭代器对象的删除方法!
可是我还是没有明白元素没有被删除的原因,,,
平菇虾饺 2013-12-03
  • 打赏
  • 举报
回复
引用 2 楼 jackwumengfeng 的回复:
for (int i = 0 ; i < list.size() ; i ++) { if(list.get(i).isCheck()) { list.remove(i); } } List中删除元素用这种方法不行吧
不应该不行的呀,,, 这是api里面指代的: public E remove(int index)移除此列表中指定位置处的元素。将任何后续元素向左移(从索引中减 1)。返回从列表中删除的元素。 指定者: 接口 List<E> 中的 remove 覆盖: 类 AbstractSequentialList<E> 中的 remove 参数: index - 要移除的元素的索引 返回: 以前在指定位置的元素 抛出: IndexOutOfBoundsException - 如果索引超出范围 (index < 0 || index >= size())
ganshenml 2013-12-03
  • 打赏
  • 举报
回复
把list放进迭代器中,利用这个迭代器遍历到你需要对应的数据处然后调用迭代器对象的删除方法!
南猿北蛰 2013-12-03
  • 打赏
  • 举报
回复
for (int i = 0 ; i < list.size() ; i ++) { if(list.get(i).isCheck()) { list.remove(i); } } List中删除元素用这种方法不行吧
平菇虾饺 2013-12-03
  • 打赏
  • 举报
回复
相当期待有人能为我解答!

67,515

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧