从列表中<Object>删除多个元素范围



我的对象列表可以有这样的元素 EG1:

[vale11, value12, value13, null, null, null, value21, value22, value23, value31, value32, value33]

EG2:

[vale11, value12, value13, null, null, null, null, null, null, value31, value32, value33]

EG3:

[vale11, value12, value13, null, null, null, value21, value22, value23, null, null, null]

EG4:

[vale11, null, value13, null, null, null, value21, value22, value23, value31, value32, null]

我想删除空值,但不是全部(注意eg4(,并且只删除从某个索引开始的范围内的空值。 所以在eg1中是这样的:

list.sublist(3, 6).clear();

EG2

list.sublist(3, 6).clear();
list.sublist(6, 9).clear();//it's not going to work

我知道起始索引和许多下一个元素(总是相同的(

有时是 1 个范围,有时是 3 、5 ... 如何使用循环或流清除原始列表?

你可以稍微改变一下你的技术:按降序排列初始索引的范围。这里的基本原理是,只要您从较高的索引转到较低的索引,并且范围不会"交叉",索引将保持一致。

因此,清除sublist(6, 9)然后sublist(3, 6)将毫无问题地工作:

//  0        1       2       3     4     5     6     7     8      9       10       11
[vale11, value12, value13, null, null, null, null, null, null, value31, value32, value33]
//                                           ^^^^^^^^^^^^^^^^ [6, 9)
//                         ^^^^^^^^^^^^^^^^ [3, 6)

使用可以通过循环来实现:

下面的方法将删除其startIndex <= index <= endIndex

<T> List<T> chopList(List<T> originalList, int startIndex, int endIndex) {
// Your code to check original list, validate startIndex, endIndex must inrange...
return IntStream.range(0, originalList.size() - 1)
.filter(i -> i < startIndex || i > endIndex)
.mapToObj(originalList::get)
.collect(toList());
}

如果要从List中删除null元素,可以像

list.removeIf(Objects::isNull);

当然,您可以将操作限制在一定范围内,例如

list.subList(start, end).removeIf(Objects::isNull);

如果实际任务是从列表中删除预定义的范围(并且这些位置可能有null元素的信息实际上无关紧要(,则可以使用此答案(按降序处理范围(,如果范围不重叠。

如果范围可能重叠,您可以使用

BitSet toRemove = new BitSet(list.size());
toRemove.set(firstRangeStart, firstRangeEnd);
toRemove.set(secondRangeStart, secondRangeEnd);
// etc
for(int e = toRemove.length(), s; e > 0; e = toRemove.previousSetBit(s)+1)
list.subList((s=toRemove.previousClearBit(e-1))+1, e).clear();

这将融合相邻和重叠的范围,然后按降序处理生成的范围。

最新更新