我试图删除数组列表中开始和结束标记之间的所有元素。
My list and My tags:
String startTag = "<p>";
String endTag = "</p>";
List<String> elements = new ArrayList<>();
假设我的列表是这样的:
[<text>, <p>, <text>, clean me, </text>, </p>, </text>]
我只想删除指定标签和标签本身之间的内容。这是我的代码:
boolean delete = false;
List<String> remove = new ArrayList<>();
for(String element : elements) {
if(delete) {
remove.add(element);
}
if(element.startsWith(startTag)) {
delete = true;
remove.add(element);
}
if(element.endsWith(endTag)) {
delete = false;
remove.add(element);
}
}
elements.removeAll(remove);
}
list "remove"之后是:
[<p>, <text>, clean me, </text>, </p>, </p>]
因此,从列表中删除这些元素后,它看起来是这样的:
[]
当它看起来像这样:
[<text>, </text>]
如何防止有重复项的字符串在删除范围之外被删除?
我怎么能防止字符串谁有重复被删除时,他们是删除范围之外?
通过元素索引而不是元素值来标识要删除的范围。有很多方法可以做到这一点,但这里有一个我喜欢的:
List<String> remainingElements = elements;
List<String> result = new ArrayList<>();
for (int start = remainingElements.indexOf(startTag);
start >= 0;
start = remainingElements.indexOf(startTag)) {
List<String> tail = remainingElements.subList(start, remainingElements.size());
int end = tail.indexOf(endTag);
if (end >= 0) {
List<String> range = tail.subList(0, end + 1);
result.addAll(range);
range.clear();
remainingElements = tail;
} else {
break;
}
}
特别要注意,子列表是由它的父列表支持的,所以对前者的修改会反映在后者中。
还请注意,这里提供的细节遵循原始示例的明显思想:它们将startTag
的第一次出现与endTag
的第一次出现相匹配。如果需要考虑标签嵌套,这可能不是您真正想要的。例如,用startTag = "<text>"; endTag = "</text>";
得到的结果是[</p>, </text>]
。在这种情况下,您仍然可以使用subList
,但您需要更聪明地识别范围边界。
使用Iterator(这是安全的并发修改)删除元素,而不是添加到removelist
boolean delete = false;
Iterator it = elements.iterator();
while(it.hasNext()) {
String element it.next();
if(delete)
it.remove();
if(element.startsWith(startTag)) {
delete = true;
it.remove();
}
if(element.endsWith(endTag)) {
delete = false;
it.remove();
}
}
}