当前位置: 首页 > 知识库问答 >
问题:

为什么我的树集不添加第一个元素以外的任何内容?

韩单弓
2023-03-14

我的表格中有几个数组:

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

然后我做了一个这样的树集:

TreeSet<Patient> patTreeSet = new TreeSet<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时,一切都很好。所以我猜我用错了树集。

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

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

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

}

然后只有“约翰”的指纹,这显然不应该是这样的。。。那么,我是否完全误用了树集?

提前感谢任何帮助!

编辑如下

====================================

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()方法

共有1个答案

宋望
2023-03-14

如果你把你的对象放在一个TreeSet中,你需要在构造函数中提供一个比较器接口的实现,或者你需要你的对象属于一个实现可比的类。

您说您从Comparable界面实现了compareTo,但在您的评论中,您说您没有,所以我正确地假设您只返回0 比较中选择code>,方法?这可以解释您的问题,因为TreeSet会根据compareTo方法结果认为您的所有对象都是“相同的”。

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

TreeSet的Javadoc表示:

请注意,如果要正确实现Set接口,由set维护的顺序(无论是否提供显式比较器)必须与equals一致。

实现这一点的最简单方法是让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或书籍)关于TreeSetHashSet以及等于compareTohashCode方法的重要性。如果你想把你的对象放在Set或Map中,你需要知道这些才能正确实现。

注:我基于您的equals方法将此方法与方法进行比较。您第一次调用toString是在比较出生日期。这不是一种很好的方法——可以在java中使用equals方法。util。直接约会。在compareTo方法中,问题会变得更糟,因为按字母顺序排序时,日期排序不正确<代码>java。util。日期还实现了可比性,因此您可以将方法中的比较替换为:

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

此外,如果任何字段可能是null,您也需要检查它。

 类似资料:
  • 问题内容: 我有几个数组的形式: 然后我制作一个TreeSet像这样: 其中Patient是制造“ Patient”对象的不同类。然后,我遍历数组中的每个元素以创建多个患者,并将它们添加到我的体内,如下所示: 但是,当我去检查我的计算机时,它仅返回“ 1”-为什么会这样? 我知道我的对象运行良好,因为当我尝试执行相同的操作但使用相反的方法时,一切正常。所以我猜我在使用TreeSet错误。 如果有帮

  • 问题内容: 我有这种方法,可以在登录前检查用户名和密码。现在,我的for循环仅检查第一个项目,它发现第一个项目不满足第一个条件,因此与其去检查第二个项目,它只是中断并返回null。 为什么会这样? 这是我的方法: 问题答案: 因此,请尝试此代码。

  • 现在,我正在尝试编写一个二叉堆,Java在二叉树结构上实现,虽然我确实很好地掌握了如何在添加元素后“堆化”树,但在堆底部找到第一个未占用叶子的逻辑让我困惑。 我知道找到第一片未被占用的叶子应该是广度优先遍历,但我仍然不知道广度优先遍历算法到底是如何工作的。

  • 我正在为C班的期末考试而学习。我们的教授给了我们这个练习题: 解释为什么代码会产生以下输出: 该问题的示例答案是: cout语句只是循环遍历数组元素,其下标由for循环的增量定义。数组初始化不定义元素大小。for循环定义了数组的大小,它碰巧超过了初始化元素的数量,因此最后一个元素默认为零。第一个for循环打印元素0(120),第二个打印元素1(200),第三个循环打印元素2(16),第四个循环打印

  • 问题内容: 我正在尝试使用排序字符串数组。这是我的代码: 现在的输出是: 我得到的是结果,但不是我想得到的结果,它们是: 如何调整代码以正确地对字符串数组进行排序? 问题答案: 你的输出是正确的。开头用“ Hello”和“ This”的白色字符表示。 另一个问题是你的方法。使用方法: 输出: 这里数组“ is”的第三个元素应该是“ Is”,否则它将在排序后排在最后。因为sort方法在内部使用ASC

  • 问题内容: 为什么我添加到ArrayList中对象只包N个最后一个元素? 问题答案: 此问题有两个典型的原因: 你存储在列表中的对象使用的静态字段 意外将同一对象添加到列表 静态场 如果列表中的对象将数据存储在静态字段中,则列表中的每个对象将看起来是相同的,因为它们具有相同的值。考虑下面的类: 在该示例中,由于声明了,因此在所有实例之间只有一个共享。(请参阅“了解班级成员”教程。) 如果使用以下代