热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

当我向javaHashSet添加元素时,所有元素都会发生变化

如何解决《当我向javaHashSet添加元素时,所有元素都会发生变化》经验,为你挑选了1个好方法。

在康威的生命游戏模拟器中,我有八个代码块,看起来像这样找到一个单元格的邻域.

int count = 0;
    p.setLocation(p.x-1, p.y-1); //upper left
    if( data.contains(p) ) ++count;
    else if( addingDeadCells ) {
        deadCellsToCheck.add(p);
        for( Point z : deadCellsToCheck ) 
            System.out.println(z.toString() + " " + z.hashCode()); 
        System.out.println();
    }

p是表示当前单元格的点,data是包含活动单元格的HashSet.为了提高效率,我只检查与活细胞相邻的死细胞,因此deadCellsToCheck是另一个HashSet,它将每一代开始为空.每次执行deadCellsToCheck.add(p)时,似乎已经在其中的所有单元都被覆盖为刚添加的单元,因为输出如下所示:

java.awt.Point[x=0,y=0] 0

java.awt.Point[x=1,y=0] 1072693248
java.awt.Point[x=1,y=0] 1072693248

java.awt.Point[x=2,y=0] 1073741824
java.awt.Point[x=2,y=0] 1073741824
java.awt.Point[x=2,y=0] 1073741824
etc...

我不认为这可能有多种原因.有任何想法吗?



1> Jaroslaw Paw..:

出现此问题的原因是您HashSet包含Point多次相同的实例.p.setLocation(p.x-1, p.y-1);您应该创建一个新点并将其添加到集合中,而不是编辑点:

int count = 0;
p = new Point(p.x-1, p.y-1); // new point here
if (data.contains(p)) {
     count++;
} else if (addingDeadCells) {
    deadCellsToCheck.add(p);
    for (Point z : deadCellsToCheck)  {
        System.out.println(z.toString() + " " + z.hashCode());
    }
    System.out.println();
}

您当前的结构也违反了hashCode()方法合同:

每当在执行Java应用程序期间多次在同一对象上调用它时,hashCode方法必须始终返回相同的整数

hashCodeequals方法使用的一套以消除重复.你创造了(0,0)具有的点hashcode = 0.然后将点修改为(1,0),其haschode更改为,1072693248因此set允许再次插入此点.但它是相同的实例 - 它是在集合中插入两次的相同对象.

可变对象通常不应该依赖于hashcode方法的集合或其他数据结构.

解决方案是使点不可变(如果你使用java.awt.Point,我建议你创建自己的类):

public class Point {

     private final int x;
     private final int y;

     public Point(int x, int y) {
         this.x = x;
         this.y = y;
     }

     // hashcode and equals methods
     // getters and utility methods

}


推荐阅读
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 从 .NET 转 Java 的自学之路:IO 流基础篇
    本文详细介绍了 Java 中的 IO 流,包括字节流和字符流的基本概念及其操作方式。探讨了如何处理不同类型的文件数据,并结合编码机制确保字符数据的正确读写。同时,文中还涵盖了装饰设计模式的应用,以及多种常见的 IO 操作实例。 ... [详细]
  • 本文详细介绍了Java中org.neo4j.helpers.collection.Iterators.single()方法的功能、使用场景及代码示例,帮助开发者更好地理解和应用该方法。 ... [详细]
  • Explore a common issue encountered when implementing an OAuth 1.0a API, specifically the inability to encode null objects and how to resolve it. ... [详细]
  • Java 类成员初始化顺序与数组创建
    本文探讨了Java中类成员的初始化顺序、静态引入、可变参数以及finalize方法的应用。通过具体的代码示例,详细解释了这些概念及其在实际编程中的使用。 ... [详细]
  • 本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ... [详细]
  • 本文详细介绍了Java中org.eclipse.ui.forms.widgets.ExpandableComposite类的addExpansionListener()方法,并提供了多个实际代码示例,帮助开发者更好地理解和使用该方法。这些示例来源于多个知名开源项目,具有很高的参考价值。 ... [详细]
  • 本文详细介绍了Akka中的BackoffSupervisor机制,探讨其在处理持久化失败和Actor重启时的应用。通过具体示例,展示了如何配置和使用BackoffSupervisor以实现更细粒度的异常处理。 ... [详细]
  • 2023年京东Android面试真题解析与经验分享
    本文由一位拥有6年Android开发经验的工程师撰写,详细解析了京东面试中常见的技术问题。涵盖引用传递、Handler机制、ListView优化、多线程控制及ANR处理等核心知识点。 ... [详细]
  • 本文详细介绍了 Java 中 org.apache.xmlbeans.SchemaType 类的 getBaseEnumType() 方法,提供了多个代码示例,并解释了其在不同场景下的使用方法。 ... [详细]
  • Scala 实现 UTF-8 编码属性文件读取与克隆
    本文介绍如何使用 Scala 以 UTF-8 编码方式读取属性文件,并实现属性文件的克隆功能。通过这种方式,可以确保配置文件在多线程环境下的一致性和高效性。 ... [详细]
  • golang常用库:配置文件解析库/管理工具viper使用
    golang常用库:配置文件解析库管理工具-viper使用-一、viper简介viper配置管理解析库,是由大神SteveFrancia开发,他在google领导着golang的 ... [详细]
  • Android 渐变圆环加载控件实现
    本文介绍了如何在 Android 中创建一个自定义的渐变圆环加载控件,该控件已在多个知名应用中使用。我们将详细探讨其工作原理和实现方法。 ... [详细]
  • 本文探讨了如何优化和正确配置Kafka Streams应用程序以确保准确的状态存储查询。通过调整配置参数和代码逻辑,可以有效解决数据不一致的问题。 ... [详细]
author-avatar
忧伤丿稻草展
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有