热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

JavaCollection移除元素方法及注意事项

这篇文章主要介绍了JavaCollection移除元素方法及注意事项,通过一个简单实例给大家讲解,需要的朋友可以参考下

1. 前言

操作集合是一个 Java 编程人员几乎每天都在重复的事情。今天我们来研究一下从 Java Collection 中删除元素的方法。我构建了一个简单的集合,我们以此为例子来展开探索。

 List servers = new ArrayList<>();
 servers.add("Felordcn");
 servers.add("Tomcat");
 servers.add("Jetty");
 servers.add("Undertow");
 servers.add("Resin");

2. for 循环并不一定能从集合中移除元素

让我们使用传统的 foreach 循环移除 F 开头的假服务器,但是你会发现这种操作引发了 ConcurrentModificationException 异常。

 // 错误的示范 千万不要使用
 for (String server : servers) {
 if (server.startsWith("F")) {
 servers.remove(server);
 }
 }

难道 for 循环就不能移除元素了吗?当然不是!我们如果能确定需要被移除的元素的索引还是可以的。

 // 这种方式是可行
 for (int i = 0; i 

但是这种方式我目前只演示了 ArrayList,其它的类型并没有严格测试,留给你自己探索。

3. 迭代器 Iterator 可以删除集合中的元素

在传统方式中我们使用 Iterator 是可以保证删除元素的:

 Iterator iterator = servers.iterator();

 while (iterator.hasNext()) {
  String next = iterator.next();
  if (next.startsWith("F")) {
  iterator.remove();
  }
 }

4. 遍历删除元素的缺点

  • 我们需要遍历集合的每一个元素并对它们进行断言,哪怕你删除一个元素。
  • 尽管我们可以通过迭代的方式删除特定的元素,但是操作繁琐,根据集合类型的不同有潜在的 ConcurrentModificationException 异常。
  • 根据数据结构的不同,删除元素的时间复杂度也大大不同。比如数组结构的 ArrayList 在删除元素的速度上不如链表结构的 LinkedList。

5. 新的集合元素删除操作

Java 8 提供了新的集合操作 API 和 Stream 来帮助我们解决这个问题。我在以前的文章中已经介绍了 Java 8 Stream API,如果有兴趣可以去看看。

5.1 Collection.removeIf()

新的 Collection Api removeIf(Predicate<&#63; super E> filter) 。该 Api 提供了一种更简洁的使用 Predicate (断言)删除元素的方法,于是我们可以更加简洁的实现开始的需求:

servers.removeIf(s-> s.startsWith("F"));

同时根据测试,ArrayList 和 LinkedList 的性能接近。一般推荐使用这种方式进行操作。

5.2 Stream 实现移除元素

和上面所有移除操作不同的是,其实任何操作都不会改变 Stream 源,我们仅仅是使用 Stream Api 操作数据源的副本。遵循了 数据源 -> 中间操作 -> 归纳终止 的生命周期。我们来看看使用 Stream 如何实现我们的意图。

5.2.1 通过 filter 断言实现

我们可以使用 Stream 的 filter 断言。filter 断言会把符合断言的流元素汇集成一个新的流,然后归纳起来即可,于是我们可以这么写:

// 跟以上不同的是 该方式中的断言是取反的操作。
List newServers = servers.stream().filter(s -> !s.startsWith("F")).collect(Collectors.toList());

这个优点上面已经说了不会影响原始数据,生成的是一个副本。缺点就是可能会有内存占用问题。

5.2.2 通过 Collectors.partitioningBy 归纳

这种方法虽然可以满足需要但是我感觉有点投机取巧的成份。Collectors.partitioningBy() 方法本意是做二分类的。该方法会将流中符合断言的、不符合断言的元素分别归纳到两个 key 分别为 true 和 false 的 Map 中,我们可以归类得到符合和不符合的元素集。实现如下:

Map> f = servers.stream().collect(Collectors.partitioningBy(s -> !s.startsWith("F")));
 
 List trues = f.get(Boolean.TRUE);
 System.out.println("不以 F 开头的: " + trues);

 List falses = f.get(Boolean.FALSE);
 System.out.println("以 F 开头的: " + falses);

一般该方式不推荐在此场景使用,并不符合该 Api 的设计意图。

6. 总结

今天我们研究了一些从 Collections 中删除元素的方法 及其注意事项。希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!


推荐阅读
  • 解读中台架构:微服务与分布式技术的区别及应用
    中心化与去中心化是长期讨论的话题。中心化架构的优势在于部署和维护相对简单,尤其在服务负载较为稳定的情况下,能够提供高效稳定的性能。然而,随着业务规模的扩大和技术需求的多样化,中心化架构的局限性逐渐显现,如扩展性和故障恢复能力较差。相比之下,微服务和分布式技术通过解耦系统组件,提高了系统的灵活性和可扩展性,更适合处理复杂多变的业务场景。本文将深入探讨中台架构中微服务与分布式技术的区别及其应用场景,帮助读者更好地理解和选择适合自身业务的技术方案。 ... [详细]
  • 2016-2017学年《网络安全实战》第三次作业
    2016-2017学年《网络安全实战》第三次作业总结了教材中关于网络信息收集技术的内容。本章主要探讨了网络踩点、网络扫描和网络查点三个关键步骤。其中,网络踩点旨在通过公开渠道收集目标信息,为后续的安全测试奠定基础,而不涉及实际的入侵行为。 ... [详细]
  • Java Web开发中的JSP:三大指令、九大隐式对象与动作标签详解
    在Java Web开发中,JSP(Java Server Pages)是一种重要的技术,用于构建动态网页。本文详细介绍了JSP的三大指令、九大隐式对象以及动作标签。三大指令包括页面指令、包含指令和标签库指令,它们分别用于设置页面属性、引入其他文件和定义自定义标签。九大隐式对象则涵盖了请求、响应、会话、应用上下文等关键组件,为开发者提供了便捷的操作接口。动作标签则通过预定义的动作来简化页面逻辑,提高开发效率。这些内容对于理解和掌握JSP技术具有重要意义。 ... [详细]
  • Spring Boot 和 Spring Cloud 是 Spring 生态系统中的重要组成部分,各自具有独特的特性和应用场景。Spring Boot 通过简化配置和自动配置机制,显著提高了开发和部署效率,减少了传统 Spring 应用中繁琐的 XML 配置文件需求。而 Spring Cloud 则在此基础上进一步提供了分布式系统的解决方案,包括服务发现、配置管理、断路器等高级功能,适用于微服务架构的构建和管理。本文将深入探讨两者的核心差异,并分析其各自的最佳应用场景。 ... [详细]
  • 基于Java和JSP的电子医疗记录管理平台
    随着信息技术的快速发展,各类管理系统已在各行各业得到广泛应用。传统的人工管理模式已逐渐无法满足现代需求。本文介绍了一种基于Java和JSP技术开发的电子医疗记录管理平台,旨在提高医疗行业的信息化水平和管理效率。该平台通过整合先进的数据库技术和Web开发框架,实现了医疗记录的高效存储、查询和管理,为医护人员提供了便捷的操作界面和强大的数据支持。 ... [详细]
  • 实现Nginx对ThinkPHP URL重写及PATHINFO支持的详细方法解析【PHP开发】
    在PHP后端开发中,实现Nginx对ThinkPHP的URL重写及PATHINFO支持是一项常见的需求。本文详细解析了经过多次尝试和研究,最终找到的一种有效配置方法,能够确保URL_MODERewrite功能正常运行,并提供稳定的服务。此外,文章还探讨了相关配置项的具体作用及其优化建议,帮助开发者更好地理解和应用这些技术。 ... [详细]
  • 在过去,我曾使用过自建MySQL服务器中的MyISAM和InnoDB存储引擎(也曾尝试过Memory引擎)。今年初,我开始转向阿里云的关系型数据库服务,并深入研究了其高效的压缩存储引擎TokuDB。TokuDB在数据压缩和处理大规模数据集方面表现出色,显著提升了存储效率和查询性能。通过实际应用,我发现TokuDB不仅能够有效减少存储成本,还能显著提高数据处理速度,特别适用于高并发和大数据量的场景。 ... [详细]
  • 在CentOS 7上部署WebRTC网关Janus
    在CentOS 7上部署WebRTC网关Janus ... [详细]
  • 在数据库设计中,谨慎使用外键至关重要。本文探讨了九个关键原因,包括数据完整性的维护、性能优化、系统复杂性的管理、数据迁移的灵活性以及对外部系统的依赖性控制。通过深入分析这些因素,可以帮助开发人员和架构师做出更明智的设计决策,确保数据库系统的高效与稳定。 ... [详细]
  • 通过使用Wireshark对POP3和SMTP协议进行详细的抓包与分析,本实验旨在帮助读者初步掌握Wireshark的使用技巧,熟悉其抓包流程,并通过实际案例深入理解这两种电子邮件协议的工作机制。此外,实验还将探讨如何利用Wireshark识别和解析协议数据包中的关键信息,为网络故障排除和安全审计提供有力支持。 ... [详细]
  • Sanic 是一个类似于 Flask 的 Python 3.5 Web 服务器,以其出色的写入速度而著称。与 Flask 不同,Sanic 支持异步请求处理,这使得它在处理高并发请求时表现更加出色。通过利用 Python 的异步特性,Sanic 能够显著提高应用程序的性能和响应能力,适用于构建高性能的异步 Web 应用。 ... [详细]
  • 在搭建Hadoop集群以处理大规模数据存储和频繁读取需求的过程中,经常会遇到各种配置难题。本文总结了作者在实际部署中遇到的典型问题,并提供了详细的解决方案,帮助读者避免常见的配置陷阱。通过这些经验分享,希望读者能够更加顺利地完成Hadoop集群的搭建和配置。 ... [详细]
  • 在PHP的设计中,预定义了9个超级全局变量、8个魔术变量和13个魔术函数,这些变量和函数无需声明即可在脚本的任意位置使用。这些特性在PHP开发中极为常见,能够显著提升开发效率和代码的灵活性。相比之下,Java并没有类似的内置机制,但通过其他方式如上下文对象和反射机制,也可以实现类似的功能。本文将详细探讨这两种语言中这些特殊变量和函数的使用方法及其应用场景。 ... [详细]
  • MySQL 数据备份与恢复的常见方法及其实践经验总结。物理备份涉及直接复制数据库文件,适用于大规模数据库环境,但无法在异构系统(如 Windows)中恢复。逻辑备份则侧重于导出建表语句和数据插入语句,便于跨平台迁移和部分数据恢复。此外,本文还探讨了增量备份、全量备份以及使用工具如 mysqldump 和 Percona XtraBackup 的具体应用场景和优缺点。 ... [详细]
  • Go 项目中数据库配置文件的优化与应用 ... [详细]
author-avatar
书友48919914
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有