dom4j中List<Element>集合使用removeIf无法删除元素节点

在学习dom4j的时候,碰到了这样一个问题,使用Element的elements的方法获得了一个List<Element>集合,使用remove(int index)方法删除指定的元素后,将doucument写入后发现节点被删除了,但是在使用removeIf删除时,写入之后发现xml文件中的元素并没有被删除,下面时当时写的代码

remove(int index)方法

public void test5_1() throws IOException{
		Element rootElement = document.getRootElement();
		List<Element> elements = rootElement.elements();
		List<Element> book = elements.get(1).elements();
		book.remove(1);
		write();//写入操作
	}

removeIf(new Predicate<T>)方法

public void test5_1() throws IOException{
		Element rootElement = document.getRootElement();
		List<Element> elements = rootElement.elements();
		List<Element> book = elements.get(1).elements();
		book.removeIf(new Predicate<Element>() {
			@Override
			public boolean test(Element t) {
				// TODO Auto-generated method stub
				if(t.getName().equals("特价")){
					return true;
				}
				return false;
			}
		});
		write();
	}

这就有点....

一开始以为使用book.removeIf(new Predicate<T>)只是删除了book集合中的数据,但并没有对document对象中的元素做更改导致的,但是为甚麽使用book.remove(int index)方法时却可以删除,这就有点说不通了

于是便开始翻看源代码,在查看list的实现类的时候发现有很多,当时不知道怎么想的,很自然的就选了ArrayList的实现,看了大半天,并没有什么收获,都只是将元素从list中集合删除。

再看list实现时突然想到,不同的实现类其中的remove方法和removeIf方法可能不一样,但是怎么知道book.remove(1)调用的是哪个实现类呢?查看dom4j的api后发现返回值elements方法的返回值也只是java.util.list并没有什么有价值的信息,如果打印它的类类型呢,果断试了以下book.getClass(),输入结果:

发现它的实现类是org.dom4j.tree.BackedList,问题似乎快要解决了,BackedList或许只是实现了list接口或是继承了它接口的实现类,并且只对remove方法做了可以删除元素的操作,但是并没有对removeIf方法做相关操作,为了验证推测,还得看下源码:

BackedList继承了ArrayList类:

接着看BackedList的remove方法:

super.remove(index)方法:

可以看出调用的是ArrayList中的remove方法,也就是先将指定的元素先从集合中删除

BackedList中remove的asNode方法

判断要删除的节点是否是Node类型的元素

BackedList中remove的removeNode方法:

最后将元素删除

接下来将是removeIf方法,但是在BackedList中并没有发现removeIf方法,那么按照继承关系它就会去它的父类中寻找removeIf方法,也就是ArrayList类中,这样的话就只能删除集合中的元素,而不是Doucment对象中的元素了,这也就解释了为什么remove方法可以删除Document中的元素,而removeIf方法不可以。

猜你喜欢

转载自blog.csdn.net/qq_33371372/article/details/82054410
今日推荐