超全模态模型 × Harness 升级,升级解锁 ArkClaw,最新支持 DeepSeek-V4 系列与 GLM-5.1
我现在有一个List<Object>,里面的元素可能是像下面这些例子的结构:
List<Object>
示例1
[vale11, value12, value13, null, null, null, value21, value22, value23, value31, value32, value33]
示例2
[vale11, value12, value13, null, null, null, null, null, null, value31, value32, value33]
示例3
[vale11, value12, value13, null, null, null, value21, value22, value23, null, null, null]
示例4
[vale11, null, value13, null, null, null, value21, value22, value23, value31, value32, null]
我的需求是:只移除指定起始索引开始的固定长度连续范围内的元素(不是所有null,比如示例4里的单个null要保留)。比如示例1里,我可以直接用list.subList(3, 6).clear();来移除索引3到5的三个null。
list.subList(3, 6).clear();
但问题来了,像示例2这种有多个需要移除的范围时,如果我按顺序执行:
list.subList(3, 6).clear(); list.subList(6, 9).clear(); // 这行代码会失效
因为第一次清除后列表长度变短了,后面的索引就偏移了,原来的索引6现在对应的元素位置已经变了。
我已经知道所有需要移除的范围的起始索引,而且每个范围的元素数量是固定的(比如都是3个),范围的数量可能是1、3、5个不等。请问怎么通过循环或者流操作来修改原List实现这个需求?
核心思路是:先处理索引更大的范围,再处理索引更小的。因为删除后面的元素不会影响前面元素的索引位置,这样就避免了索引偏移的问题。
具体步骤:
subList(startIndex, startIndex + fixedLength).clear()
假设我们的固定范围长度是3,需要移除的起始索引列表是[3, 6](对应示例2的情况):
[3, 6]
import java.util.ArrayList; import java.util.Collections; import java.util.List; public class ListRemoveExample { public static void main(String[] args) { List<Object> list = new ArrayList<>(); // 初始化示例2的列表 list.add("vale11"); list.add("value12"); list.add("value13"); list.add(null); list.add(null); list.add(null); list.add(null); list.add(null); list.add(null); list.add("value31"); list.add("value32"); list.add("value33"); // 需要移除的起始索引列表 List<Integer> startIndices = new ArrayList<>(); startIndices.add(3); startIndices.add(6); int fixedRangeLength = 3; // 降序排序起始索引 Collections.sort(startIndices, Collections.reverseOrder()); // 从后往前移除每个范围 for (int start : startIndices) { // 确保索引不会越界(可选,根据你的业务场景判断是否需要) if (start + fixedRangeLength <= list.size()) { list.subList(start, start + fixedRangeLength).clear(); } } // 输出处理后的列表 System.out.println(list); // 结果:[vale11, value12, value13, value31, value32, value33] } }
如果你想用Java 8+的流来处理,也可以这样写(本质还是降序后处理):
startIndices.stream() .sorted(Collections.reverseOrder()) .forEach(start -> { if (start + fixedRangeLength <= list.size()) { list.subList(start, start + fixedRangeLength).clear(); } });
比如示例2中,我们先处理起始索引6:移除索引6到8的三个null,此时列表长度从12变成9,原来的索引3到5的三个null位置并没有改变(因为删除的是它们后面的元素)。接着处理起始索引3,移除索引3到5的三个null,最终得到正确的结果。
而如果是从前往后处理,第一次移除索引3-5后,原来的索引6现在变成了索引3,此时再执行subList(6,9)就会超出列表长度,或者删除错误的元素。
subList(6,9)
这个方法也能完美处理你提到的示例4:因为那个单个null不在你指定的移除范围内,所以会被保留下来。
内容的提问来源于stack exchange,提问作者Mark
超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起
模型再升级,30秒超长叙事, 模态参考扩容
模型自由,工具不限,最新支持 Deepseek-V4 系列、GLM-5.3 系列
超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列
大模型19元起,Al应用9.9元畅享,新人首购爆款尽享优惠