我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Java HashSet的Removals()方法使用要注意哪些事项

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Java HashSet的Removals()方法使用要注意哪些事项

本篇内容介绍了“Java HashSet的Removals()方法使用要注意哪些事项”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

前言

我有一个集合,实际上是一个HashSet。我想从中删除一些item…其中许多item可能不存在。事实上,在我们的测试用例中,“removals”集合中的所有项都不在原始集合中。这听起来——实际上也是——非常容易编码。毕竟,我们已经准备好了。removeAll来帮助我们,对吗?

让我们把它变成一个小测试。我们在命令行上指定“source”set的大小和“removals”集合的大小,并构建它们。source set合只包含非负整数;删除集仅包含负整数。我们使用系统测量删除所有元素所需的时间System.currentTimeMillis(),它不是世界上最精确的秒表,但在这种情况下就足够了,正如您将看到的那样。

代码如下:

import java.util.*;public class Test{    public static void main(String[] args)    {        int sourceSize = Integer.parseInt(args[0]);        int <a href="https://javakk.com/tag/removals" rel="external nofollow"  rel="external nofollow"  target="_blank" >removals</a>Size = Integer.parseInt(args[1]);                Set<Integer> source = new HashSet<Integer>();        Collection<Integer> <a href="https://javakk.com/tag/removals" rel="external nofollow"  rel="external nofollow"  target="_blank" >removals</a> = new ArrayList<Integer>();                for (int i = 0; i < sourceSize; i++)        {            source.add(i);        }        for (int i = 1; i <= removalsSize; i++)        {            removals.add(-i);        }                long start = System.currentTimeMillis();        source.removeAll(removals);        long end = System.currentTimeMillis();        System.out.println("Time taken: " + (end – start) + "ms");    }}

首先,让我们给它一个简单的工作:一个包含100个items的source set,以及要删除的100个items:

c:UsersJonTest>java Test 100 100Time taken: 1ms

好吧,所以我们没想到会很慢&hellip;&hellip;很明显,我们可以把速度提高一点。一百万件items和300000件items的来源如何?

c:UsersJonTest>java Test 1000000 300000Time taken: 38ms

嗯,看起来还是挺快的。现在我觉得我有点残忍,要求它做所有这些移除。让我们让它变得更简单一些&ndash;300000个source items和300000个删除:

c:UsersJonTest>java Test 300000 300000Time taken: 178131ms

快三分钟了?哎呀!当然,从一个较小的集合中删除items应该比我们在38ms内管理的集合更容易?嗯,最终这一切都是有道理的。HashSet扩展了AbstractSet,它在removeAll方法的文档中包含此代码段:

https://docs.oracle.com/javase/6/docs/api/java/util/AbstractSet.html

此实现通过调用每个集合上的size方法来确定此集合和指定集合中的较小者。如果此集合的元素较少,则实现将迭代此集合,依次检查迭代器返回的每个元素,以查看它是否包含在指定的集合中。如果它是这样包含的,则使用迭代器的remove方法将其从该集中移除。如果指定集合的元素较少,那么实现将迭代指定集合,使用该集合的remove方法从该集合中删除迭代器返回的每个元素。

从表面上看,这听起来很合理&mdash;&mdash;遍历较小的集合,检查较大集合中是否存在。然而,这就是抽象存在漏洞的地方。仅仅因为我们可以要求一个item出现在一个大的集合中,并不意味着它会很快出现。在我们的例子中,集合的大小是相同的,但是检查哈希集中是否存在项是O(1),而在ArrayList中检查是O(N)&hellip;而每个集合的迭代成本是相同的。基本上,通过选择遍历HashSet并检查ArrayList中是否存在,我们得到了一个O(M*N)解决方案,而不是O(N)解决方案。removeAll方法基于在这种情况下无效的假设进行“优化”。

那么如何解决?

有两种简单的方法可以解决这个问题。首先,只需更改要从中删除的集合的类型。只需将ArrayList<Integer>更改为HashSet<Integer>,我们就可以回到34ms的范围。我们甚至不需要更改声明的删除类型。

第二种方法是更改我们使用的API:如果我们知道要迭代删除并在源代码中执行查找,那么很容易做到:

for (Integer value : removals){    source.remove(value);}

事实上,在我的机器上,它的性能略优于removeAll&ndash;它不需要在每次迭代时检查remove的返回值,removeAll这样做是为了返回是否删除了任何项。以上运行时间约为28ms。(我已经用相当大的数据集对其进行了测试,它确实比双哈希集方法更快。)

然而,这两种方法都需要在源代码中添加注释,以解释为什么我们没有使用最明显的代码(列表和删除)。我不能抱怨这里的文档&mdash;&mdash;它确切地说明了它将做什么。在你遇到这样的问题之前,你根本不需要担心它。

那么,实现应该做什么呢?可以说,它真的需要知道它所处理的每一个集合中什么是便宜的。在决定策略之前探索性能特征的想法对于清理我们喜欢在Java集合之类的框架中考虑的抽象是完全不可取的&hellip;&hellip;但在这种情况下,这可能是一个好主意。

“Java HashSet的Removals()方法使用要注意哪些事项”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Java HashSet的Removals()方法使用要注意哪些事项

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Java HashSet的Removals()方法使用要注意哪些事项

本篇内容介绍了“Java HashSet的Removals()方法使用要注意哪些事项”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!前言我有一
2023-07-02

java中使用equals()方法要注意哪些事项

在java中使用equals()方法时,需要注意以下几点事项:1. 避免空指针异常:在调用equals()方法之前,需要确保对象不为空。可以使用if语句或者使用Optional类来进行空值检查。2. 重写equals()方法:默认情况下,e
2023-09-15

sqlfront使用要注意哪些事项

使用SQLFront时,需要注意以下事项:确保正确输入数据库连接信息:在使用SQLFront时,需要正确输入数据库的连接信息,包括数据库名称、用户名和密码等,以确保能够成功连接到数据库。注意数据备份和恢复:在进行数据库操作时,特别是对重要数
sqlfront使用要注意哪些事项
2024-05-21

使用javaweb要注意哪些事项

1. 确保正确配置和部署Java开发环境,包括安装JDK、配置环境变量等。2. 选择适合的Java Web框架,如Spring MVC、Struts等,根据项目需求选择合适的框架。3. 编写安全的代码,注意防止常见的Web安全漏洞,如SQL
2023-09-21

使用jpa要注意哪些事项

使用JPA时需要注意以下事项:1. 实体类的注解:使用@Entity注解标记实体类,使用@Id标记实体类中的主键字段,使用@Column注解标记实体类中的属性字段。2. 关联关系的注解:使用@OneToOne、@OneToMany、@Man
2023-09-12

使用averageifs要注意哪些事项

使用averageifs函数时,需要注意以下几点事项:1. 函数语法:averageifs函数的语法为averageifs(average_range, criteria_range1, criteria1, [criteria_range
2023-09-07

prometheus使用要注意哪些事项

避免在生产环境中直接使用默认配置,建议根据具体需求进行调整和优化。确保Prometheus服务器拥有足够的资源(CPU、内存、存储)来处理收集的指标数据。定期监控Prometheus的性能,及时发现和解决潜在问题。考虑使用Promet
prometheus使用要注意哪些事项
2024-03-05

使用MongoDB要注意哪些事项

使用MongoDB时需要注意以下事项:数据建模:MongoDB是一种文档数据库,数据以文档形式存储,因此需要合理设计文档模式。考虑数据的访问模式、关系等因素来设计数据模型。索引优化:MongoDB支持创建索引来提高查询性能。在设计索引时需要
2023-10-25

Java中使用image类要注意哪些事项

在Java中使用Image类时,需要注意以下几点事项:图片文件的路径:确保图片文件的路径是正确的,并且能够被程序正确地访问到。Image对象的创建:可以通过ImageIO类的read()方法或Toolkit类的getImage()方法来创建
Java中使用image类要注意哪些事项
2024-03-07

postgresql使用要注意哪些事项

定期备份数据:定期备份是保护数据安全的重要措施,确保在意外情况下能够快速恢复数据。使用安全的认证机制:确保只有授权用户能够访问数据库,使用安全的认证机制如密码、SSL等。避免使用默认用户和密码:避免使用数据库默认的用户和密码,定期更改密码以
postgresql使用要注意哪些事项
2024-03-14

sql使用parallel要注意哪些事项

在使用SQL的parallel功能时,需要注意以下事项:确认数据库是否支持parallel功能:不是所有的数据库都支持并行查询,需要先确认数据库版本和配置是否支持parallel。调整parallel级别:可以通过设置parallel_de
sql使用parallel要注意哪些事项
2024-04-09

java递归函数使用要注意哪些事项

在使用Java递归函数时,需要注意以下几个事项:1. 基准条件:递归函数必须有一个终止条件,即基准条件。否则,递归函数将无限循环下去,导致栈溢出错误。2. 递归公式:递归函数必须包含一个递归公式,即递归调用自身的语句。这样才能实现递归的效果
2023-08-29

使用numpy库要注意哪些事项

在使用numpy库时,需要先安装好numpy库,可以使用pip命令进行安装:pip install numpy学会使用numpy中的常用函数和方法,比如创建数组、数组运算、数组切片、数组形状变换等。注意numpy中使用的数据类型,比如num
使用numpy库要注意哪些事项
2024-04-03

java调用接口要注意哪些事项

在Java中调用接口时需要注意以下几个事项:1. 接口不能直接实例化,只能通过实现接口的类来创建对象。因此,需要先创建一个实现了该接口的类的对象,然后使用该对象来调用接口中的方法。2. 在调用接口中的方法时,需要在实现类中实现该方法。如果实
2023-10-09

java调用成员要注意哪些事项

在Java中调用成员时,需要注意以下几个事项:1. 访问修饰符:成员的访问修饰符决定了它的可见范围。如果成员是private修饰的,只能在同一个类中访问;如果是protected修饰的,可以在同一个包或子类中访问;如果是默认修饰符(即没有显
2023-09-15

在java中使用static是需要注意哪些事项

在java中使用static是需要注意哪些事项?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。java基本数据类型有哪些Java的基本数据类型分为:1、整数类型,用来表示整数
2023-06-14

在java中使用final时需要注意哪些事项

在java中使用final时需要注意哪些事项?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。Java的特点有哪些Java的特点有哪些1.Java语言作为静态面向对象编程语言的代表
2023-06-14

使用Java构造器时需要注意哪些事项

今天就跟大家聊聊有关使用Java构造器时需要注意哪些事项,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Java构造器使用方法及注意事项超类的构造器在子类的构造器运行之前运行,也就是说
2023-05-31

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录