为什么我的 TreeSet 不添加第一个元素之外的任何内容?

2024-02-29

我有几个形式的数组:

private static String[] patientNames = { "John Lennon", "Paul McCartney", "George Harrison", "Ringo Starr" };

然后我制作一个像这样的 TreeSet:

TreeSet<Patient> patTreeSet = new TreeSet<Patient>();

其中 Patient 是一个创建“Patient”对象的不同类。 然后我循环遍历数组中的每个元素来创建几个患者并将它们添加到我的数组中patTreeSet像这样:

for(int i = 0; i< patientNames.length; i++){
     Date dob = date.getDate("MM/dd/yyyy", patientBirthDates[i]);
     Patient p = new PatientImpl(patientNames[i], patientSSN[i], dob);

     patTreeSet.add(p);
}

但是当我去检查我的patTreeSet.size()它只返回“1” - 这是为什么?

我知道我的对象运行良好,因为当我尝试做同样的事情但使用ArrayList相反,一切正常。所以我猜我使用 TreeSet 是错误的。

如果有帮助,Patient 有一个名为 getFirstName() 的方法,当我尝试执行以下操作时:

Iterator<Patient> patItr = patTreeSet.iterator();

while(patItr.hasNext()){
    System.out.println(patItr.next().getFirstName());

}

然后只有“John”打印,这显然不应该是这样的......那么,我是否完全滥用了 TreeSet?

预先感谢您的任何帮助!

EDIT below

================PatientImpl 类====================

public class PatientImpl implements Patient, Comparable{

    Calendar cal = new GregorianCalendar();
    private String firstName;
    private String lastName;
    private String SSN;
    private Date dob;
    private int age;
    private int thisID;             
    public static int ID = 0;       



    public PatientImpl(String fullName, String SSN, Date dob){

        String[] name = fullName.split(" ");
        firstName = name[0];
        lastName = name[1];

        this.SSN = SSN;

        this.dob = dob;

        thisID = ID += 1;
    }

@Override
    public boolean equals(Object p) {

        //for some reason casting here and reassigning the value of p doesn't take care of the need to cast in the if statement...
        p = (PatientImpl) p;

        Boolean equal = false;
        //make sure p is a patient before we even compare anything
        if (p instanceof Patient) {

            Patient temp = (Patient) p;

            if (this.firstName.equalsIgnoreCase(temp.getFirstName())) {
                if (this.lastName.equalsIgnoreCase(temp.getLastName())) {
                    if (this.SSN.equalsIgnoreCase(temp.getSSN())) {
                        if(this.dob.toString().equalsIgnoreCase(((PatientImpl) p).getDOB().toString())){
                            if(this.getID() == temp.getID()){
                                equal = true;
                            }
                        }
                    }
                }
            }
         }
        return equal;
    }

然后所有的 getter 都在下面,以及来自 Comparable 接口的compareTo()方法


如果你把你的对象放在TreeSet,您需要提供一个实现Comparator构造函数中的接口,或者您需要您的对象属于实现了Comparable.

你说你实施compareTo来自Comparable界面,但在你的评论中你说你没有,所以我假设你只是正确的return 0; in the compareTo方法?这可以解释你的问题,因为 TreeSet 会认为你的所有对象都是“相同的”compareTo方法结果。

基本上,在一个TreeSet,您的对象按排序顺序维护,并且排序由 Comparable/Comparator 方法的结果确定。这用于快速查找 TreeSet 中的重复项,并且具有额外的好处,即当您迭代 TreeSet 时,您可以按排序顺序获得结果。

Javadoc 的TreeSet says:

请注意,集合维护的顺序(无论是否是显式的) 提供比较器)必须是与等于一致如果是 正确实施Set界面。

实现这一目标的最简单方法就是让您equals方法调用compareTo方法并检查结果是否为0.

鉴于你的PatientImpl类中,我假设您希望首先按姓氏对患者进行排序,然后按名字排序,然后按类中的其余字段进行排序。

你可以实施一个compareTo像这样的方法:

@Override
public int compareTo(Object o) {
    if (!(o instanceof Patient))
        return -1;
    Patient temp = (Patient) o;
    int r = this.lastName.compareToIgnoreCase(temp.getLastName());
    if (r == 0)
        r = this.firstName.compareToIgnoreCase(temp.getFirstName());
    if (r == 0)
        r = this.SSN.compareToIgnoreCase(temp.getSSN());
    if (r == 0)
        r = this.dob.toString().compareToIgnoreCase(temp.getDOB().toString());
    if (r == 0)
        r = Integer.compare(this.getID(), temp.getID());
    return r;
}

我相信这会解决你所描述的问题。 我建议你阅读(Javadoc 或书籍)TreeSet and HashSet以及的重要性equals, compareTo and hashCode方法。 如果您想将对象放入 Set 或 Map 中,您需要了解这些才能正确实现。

Note我根据这个compareTo方法对你的equals方法。 您通过首先调用 toString 来比较出生日期。这不是一个很好的方法 - 你可以使用equals直接在 java.util.Date 中的方法。在compareTo 方法中,问题会变得更糟,因为当您按字母顺序对日期进行排序时,日期无法正确排序。java.util.Date还实现了Comparable因此您可以将方法中的比较替换为:

    if (r == 0)
        r = this.dob.compareTo(temp.getDOB());

此外,如果任何字段可以null,您还需要检查这一点。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么我的 TreeSet 不添加第一个元素之外的任何内容? 的相关文章

  • 有没有创建 Cron 表达式的 Java 代码? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我需要一个 Java 代码来根据用户输入创建一个 cron 表达式 用户输入是时间 频率和执行次数 只需从评论中添加 自己创建 即可
  • java.lang.ClassNotFoundException:javax.mail.MessagingException

    我想使用 eclipse 将电子邮件从我的 gmail 帐户发送到另一个邮件帐户 我使用 apache tomcat 7 0 34 作为我的 Web 服务器 并使用端口 8080 作为 apache 服务器 HTTP 1 1 并使用 JRE
  • 两个整数乘积的模

    我必须找到c c a b mod m a b c m 是 32 位整数 但 a b 可以超过 32 位 我正在尝试找出一种计算 c 的方法 而不使用 long 或任何 gt 32 位的数据类型 有任何想法吗 如果m是质数 事情可以简化吗 注
  • eclipse行号状态行贡献项是如何实现的?

    我需要更新状态行编辑器特定的信息 我已经有了自己的实现 但我想看看 eclipse 贡献项是如何实现的 它显示状态行中的行号 列位置 谁能指点一下 哪里可以找到源代码 提前致谢 亚历克斯 G 我一直在研究它 它非常复杂 我不确定我是否了解完
  • Java 的支持向量机?

    我想用Java编写一个 智能监视器 它可以随时发出警报detects即将到来的性能问题 我的 Java 应用程序正在以结构化格式将数据写入日志文件
  • 为什么即使我的哈希码值相同,“==”也会返回 false

    我写了一个像这样的课程 public class HashCodeImpl public int hashCode return 1 public static void main String args TODO Auto generat
  • 如何在 JPQL 或 HQL 中进行限制查询?

    在 Hibernate 3 中 有没有办法在 HQL 中执行相当于以下 MySQL 限制的操作 select from a table order by a table column desc limit 0 20 如果可能的话 我不想使用
  • Akka 与现有 java 项目集成的示例

    如果我已经有现有的javaWeb 应用程序使用spring and servlet容器 将 Akka 集成到其中的正确方法是什么 就像我将会有Actor1 and Actor2互相沟通的 开始使用这些演员的切入点是什么 例如 1 把它放在那
  • Java继承,扩展类如何影响实际类

    我正在查看 Sun 认证学习指南 其中有一段描述了最终修饰符 它说 如果程序员可以自由地扩展我们所知的 String 类文明 它可能会崩溃 他什么意思 如果可以扩展 String 类 我是否不会有一个名为 MyString 的类继承所有 S
  • 蓝牙发送和接收文本数据

    我是 Android 开发新手 我想制作一个使用蓝牙发送和接收文本的应用程序 我得到了有关发送文本的所有内容逻辑工作 但是当我尝试在手机中测试它时 我看不到界面 这是Main Activity Code import android sup
  • Jetty、websocket、java.lang.RuntimeException:无法加载平台配置器

    我尝试在 Endpoint 中获取 http 会话 我遵循了这个建议https stackoverflow com a 17994303 https stackoverflow com a 17994303 这就是我这样做的原因 publi
  • 如何将 HTML 链接放入电子邮件正文中?

    我有一个可以发送邮件的应用程序 用 Java 实现 我想在邮件中放置一个 HTML 链接 但该链接显示为普通字母 而不是 HTML 链接 我怎样才能将 HTML 链接放入字符串中 我需要特殊字符吗 太感谢了 Update 大家好你们好 感谢
  • 使用 Elastic Beanstalk 进行 Logback

    我在使用 Elastic Beanstalk 记录应用程序日志时遇到问题 我正在 AWS Elastic Beanstalk 上的 Tomcat 8 5 with Corretto 11 running on 64bit Amazon Li
  • 在 Java 中获取并存储子进程的输出

    我正在做一些需要我开始子处理 命令提示符 并在其上执行一些命令的事情 我需要从子进程获取输出并将其存储在文件或字符串中 这是我到目前为止所做的 但它不起作用 public static void main String args try R
  • hibernate 6.0.2.Final 和 spring boot 2.7.0 的entityManagerFactory bean 未配置问题

    所以最近我想升级我的 Spring Boot 项目项目的一些依赖项 特别是这些组件 雅加达 EE 9 弹簧靴2 7 休眠 6 0 2 Final 完成此操作后 所有更新和代码折射 更新将 javax 导入到 jakarta 以及一些 hib
  • 将 JavaFX FXML 对象分组在一起

    非常具有描述性和信息性的答案将从我这里获得价值 50 声望的赏金 我正在 JavaFX 中开发一个应用程序 对于视图 我使用 FXML
  • 部署 .war 时出现 Glassfish 服务器错误:部署期间发生错误:准备应用程序时出现异常:资源无效

    我正在使用以下内容 NetBeans IDE 7 3 内部版本 201306052037 爪哇 1 7 0 17 Java HotSpot TM 64 位服务器虚拟机 23 7 b01 NetBeans 集成 GlassFish Serve
  • 在 Spring 上下文中查找方法级自定义注释

    我想知道的是 所有的类 方法Spring http en wikipedia org wiki Spring Framework注释为 Versioned的bean 我创建了自定义注释 Target ElementType METHOD E
  • java 中的蓝牙 (J2SE)

    我是蓝牙新手 这就是我想做的事情 我想获取连接到我的电脑上的蓝牙的设备信息并将该信息写入文件中 我应该使用哪个 api 以及如何实现 我遇到了 bluecove 但经过几次搜索 我发现 bluecove 不能在 64 位电脑上运行 我现在应
  • Java/Python 中的快速 IPC/Socket 通信

    我的应用程序中需要两个进程 Java 和 Python 进行通信 我注意到套接字通信占用了 93 的运行时间 为什么通讯这么慢 我应该寻找套接字通信的替代方案还是可以使其更快 更新 我发现了一个简单的修复方法 由于某些未知原因 缓冲输出流似

随机推荐