Java List移除相应元素的超简洁写法分享

 更新时间:2021年11月17日 09:29:59   作者:氢电公敌  
这篇文章主要介绍了Java List移除相应元素的超简洁写法,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

List移除相应元素的超简洁写法

最近遇到了一个需求(好吧以前也遇到过),就是将一个List中的部分元素去除,如把string中带数字的元素去除,以前是各种遍历各种不爽,今天发现用Java8中的lambda写,只需三行。

好了上代码

List<String> list = new ArrayList<String>(){ 
    {
        // 为list添加数据
        addAll(Arrays.asList("wangzhen456liupei123".split("")));
        add("1521"); // 纯数字数据
        add("wanghzen123") // 数字+字符数据
        add("wangzhen"); // 纯字符串 
    }
};
System.out.println("初始数据:" + list);
Pattern pattern = Pattern.compile("\\d");//匹配数字
Predicate<String> filter = s -> pattern.matcher(s).find();
list.removeIf(filter);//移除
System.out.println(list);

输出如下:

初始数据:[w, a, n, g, z, h, e, n, 4, 5, 6, l, i, u, p, e, i, 1, 2, 3, 1521, wangzhen] [w, a, n, g, z, h, e, n, l, i, u, p, e, i, wangzhen]

其实有机智的朋友可能已经发现了,不要说三行了,一行都可以:

list.removeIf(s -> Pattern.compile("\\d").matcher(s).find());

虽说如果你想这样写也没人能拦着你(同时你也要确定三个月之后依然能看懂)。但是从代码的可读性和可维护性角度来讲,倒是不如前面三行的那个写法。

总结:越精简的代码就越应该有注释,不然哪天手一抽就Ctrl+/了 XD

Java List 删除元素

在Java中,使用List时想要删除某个特定个元素怎么办?很好办!因为List接口有remove()这个方法,我们只需要调用remove()方法,就可以删除list中的某个元素。但是list自带的有一些坑,在相邻有相同元素时会掉坑:

使用list.remove()删除:

我们看到有两个“a”元素相邻,但是删除时却只删除了一个,这是为何呢?因为删除时,每删除一个元素,后边的元素都会左移一位,也就是下标会减1,在for循环中,删除第一个“a”时,i(下标)为0,此时list重排,后边的元素全部左移1位,也就是说第二个“a”元素的下标从1变为了0,而此时for循环进行已经第二次循环了,执行了i++,i的值为1,对应为“b”元素,然后向后循环,再也找不到“a”元素了。所以相邻元素有重复的话,只能删除一个。这明显不符合我们的需求。

那解决办法是什么呢?

1.删除后元素后,i-1

删除一个元素后,后边的元素左移1位,此时i-1,保证了下次循环能访问到左移了1位的元素。

2.反向删除

我们先从后边的元素开始循环,一个一个的往前面循环,找出特定元素删除

这样,就算删除了倒数第一个"a"元素,list重排,也只是把后边的元素左移1位,此时倒数第一个“a”元素(下标为1)被删除,接着b替代了a成为了下标为1的元素,但前边的元素不变,i-- = 0 后依然能够找到其相邻的a元素。

3.使用迭代器删除(iterator)(推荐)

Iterator.remove() 方法会在删除当前迭代对象的同时,会保留原来元素的索引。所以用迭代删除元素是最保险的方法,建议大家使用List过程,这其实和上面第一中方法类似,只不过iterator内部帮我们做了类似i-1的操作。推荐使用这种做法,因为我们不保证每次都记得手动把下标减去1。

4.赋值给新的list

其实我们可以转换思维,可以过滤掉不需要的元素后赋值给新的list对象,利用java8的lambda表达式和强大的stream流形式进行内部迭代来过滤掉特定元素,我们只需一行代码就可以实现。虽然这种方式比较简洁,但是定义了新变量,旧的list就只能等待漫长的gc了。

注意:在进行普通for循环删除时,不要把list.size()抽离出去赋值给变量,然后用此变量做为for条件, 因为删除时,list.size()的值是会改变的,要把list.size作为for条件。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java泛型的简单实例

    Java泛型的简单实例

    这篇文章介绍了Java泛型的简单实例,有需要的朋友可以参考一下
    2013-10-10
  • Java Vector类详解及实例代码

    Java Vector类详解及实例代码

    这篇文章主要介绍了Java Vector类详解及实例代码的相关资料,需要的朋友可以参考下
    2017-01-01
  • SpringBoot+SpringSession+Redis实现session共享及唯一登录示例

    SpringBoot+SpringSession+Redis实现session共享及唯一登录示例

    这篇文章主要介绍了SpringBoot+SpringSession+Redis实现session共享及唯一登录示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • Maven之远程仓库的配置详解

    Maven之远程仓库的配置详解

    这篇文章主要介绍了Maven之远程仓库的配置详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • spring依赖注入知识点分享

    spring依赖注入知识点分享

    在本篇文章里小编给大家整理的是关于spring依赖注入知识点以及相关代码内容,需要的朋友们学习下。
    2019-11-11
  • java唯一字符串ID生成方案详解

    java唯一字符串ID生成方案详解

    这篇文章主要给大家介绍了关于java唯一字符串ID生成方案的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-10-10
  • java多线程Thread-per-Message模式详解

    java多线程Thread-per-Message模式详解

    本篇文章给大家分享java多线程Thread-per-Message模式的相关知识点,对此有兴趣的朋友参考学习下。
    2018-05-05
  • 浅谈Java中replace与replaceAll区别

    浅谈Java中replace与replaceAll区别

    这篇文章主要介绍了Java中replace与replaceAll区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-03-03
  • java+testng+selenium的自动化测试实例

    java+testng+selenium的自动化测试实例

    这篇文章主要介绍了java+testng+selenium的自动化测试实例,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • Java 无符号右移与右移运算符的使用介绍

    Java 无符号右移与右移运算符的使用介绍

    这篇文章主要介绍了Java 无符号右移与右移运算符的使用介绍,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-06-06

最新评论