Reputation: 273
My list of objects can have such elements 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]
I want to remove the null values but not all (note eg4) and only those in a range started from certain index. So in eg1 would be something like:
list.sublist(3, 6).clear();
eg2:
list.sublist(3, 6).clear();
list.sublist(6, 9).clear();//it's not going to work
I know the starting indexes and a number of next elements (always the same)
Sometimes it would be 1 range, sometimes 3 , 5 ... How to clear the original list with the use of a loop or streams ?
Upvotes: 3
Views: 304
Reputation: 298429
If you want to remove null
elements from a List
, you can do it as simple as
list.removeIf(Objects::isNull);
Of course, you can restrict the operation to a certain range like
list.subList(start, end).removeIf(Objects::isNull);
If the actual task is to remove predefined ranges from a list (and the information that there might be null
elements at these place is actually irrelevant), you can use this answer (process the ranges in descending order), if the ranges don’t overlap.
If the ranges might overlap, you can use
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();
This will fuse adjacent and overlapping ranges before processing the resulting ranges in descending order.
Upvotes: 0
Reputation: 18235
Use can do it with a loop:
Below method will remove the elements whose 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());
}
Upvotes: 0
Reputation: 726849
You can use your technique with a little twist: order your ranges on the initial index in descending order. The rationale here is that as long as you go from a higher index to a lower index, and the ranges do not "cross over", the indexing is going to remain consistent.
Hence, clearing out sublist(6, 9)
followed by sublist(3, 6)
is going to work without a problem:
// 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)
Upvotes: 2