如何获取inputList中不在forbiddenList的元素?非Java8内联方法实现
问题分析与优化方案
一、先纠正原代码的逻辑错误
你的需求是保留inputList中未出现在forbiddenList里的元素,但当前代码遍历的是forbiddenList,把不在inputList里的元素加入结果,这和需求完全相反。正确的基础逻辑应该是遍历inputList,筛选出不在forbiddenList中的元素。
二、优化实现方案
方案1:直接复用inputList(修改原列表)
如果允许直接修改inputList作为最终结果,不需要新建列表,可以用迭代器遍历并删除符合条件的元素(注意不能用普通for循环或增强for循环删除,会触发ConcurrentModificationException):
// 先把forbiddenList转成HashSet,把查询复杂度从O(n)降到O(1) Set<String> forbiddenSet = new HashSet<>(forbiddenList); Iterator<String> iterator = inputList.iterator(); while (iterator.hasNext()) { String ele = iterator.next(); if (forbiddenSet.contains(ele)) { iterator.remove(); } } // 此时inputList就是你要的结果列表
这个方案的优势:
- 完全复用原inputList,无需新建集合对象
- 用HashSet优化查询性能,整体时间复杂度从原逻辑的O(m*n)(m为inputList长度,n为forbiddenList长度)降到O(m+n),数据量越大性能提升越明显
方案2:不修改原inputList,新建结果列表但优化性能
如果不能改动原inputList,那还是需要新建列表,但同样可以用HashSet优化查询效率:
Set<String> forbiddenSet = new HashSet<>(forbiddenList); // 初始化时指定容量,避免后续扩容带来的性能损耗 List<String> finalList = new ArrayList<>(inputList.size()); for (String ele : inputList) { if (!forbiddenSet.contains(ele)) { finalList.add(ele); } }
三、补充:倒序遍历删除的替代方式
如果不想用迭代器,也可以用倒序for循环删除元素(避免索引越界),但可读性不如迭代器:
Set<String> forbiddenSet = new HashSet<>(forbiddenList); for (int i = inputList.size() - 1; i >= 0; i--) { if (forbiddenSet.contains(inputList.get(i))) { inputList.remove(i); } }
内容的提问来源于stack exchange,提问作者Martin Moore
相关产品推荐
相关产品推荐

