为什么我的TreeSet不会添加除第一个元素之外的任何内容?
我在表单中有几个数组:
private static String[] patientNames = { "John Lennon", "Paul McCartney", "George Harrison", "Ringo Starr" };
然后我像这样制作一个TreeSet:
TreeSet patTreeSet = new TreeSet();
患者是另一类产生“患者”对象的人。 然后我遍历我的数组中的每个元素来创建几个患者并将它们添加到我的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错误。
如果有帮助,患者有一个名为getFirstName()的方法,当我尝试执行以下操作时:
Iterator patItr = patTreeSet.iterator(); while(patItr.hasNext()){ System.out.println(patItr.next().getFirstName()); }
然后只有“John”打印,显然不应该这样……所以,我是否完全滥用TreeSet?
在此先感谢您的帮助!
编辑如下
================ PatientImpl Class ====================
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
的类。
你说你从Comparable
接口实现了compareTo
,但是在你的评论中你说你没有,所以我假设你只return 0;
是正确的return 0;
在compareTo
方法? 这可以解释你的问题,因为TreeSet会根据compareTo
方法结果认为你的所有对象都是“相同的”。
基本上,在TreeSet
,您的对象按排序顺序维护,排序由Comparable / Comparator方法的结果决定。 这用于快速查找TreeSet中的重复项,并且具有额外的好处,当您遍历TreeSet时,您将按排序顺序获得结果。
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; }
我相信这可以解决你描述的问题。 我建议你在TreeSet
和HashSet
上阅读(Javadoc或书籍)以及equals
, compareTo
和hashCode
方法的重要性。 如果要将对象放在Set或Map中,则需要了解这些对象才能正确实现。
注意我在你的equals
方法上使用了compareTo
方法。 您通过首先调用toString来比较日期或出生日期。 这不是一个非常好的方法 – 您可以直接在java.util.Date中使用equals
方法。 在compareTo方法中,问题变得更糟,因为按字母顺序对日期排序时日期无法正确排序。 java.util.Date
还实现了Comparable
因此您可以使用以下方法替换该方法中的比较:
if (r == 0) r = this.dob.compareTo(temp.getDOB());
此外,如果任何字段可以为null
,则还需要检查它。
- JUnit抛出java.lang.NoSuchMethodError对于com.google.common.collect.Iterables.tryFind
- 腐败的表格数据:过早结束
- 在maven中运行单个测试 – >没有执行任何测试!
- 如何在JTable中设置特定单元格的值?
- 尝试运行我的项目时抛出BeanCreationException
- 使用Java lambda而不是’if else’
- 需要用于php加密脚本的similler java代码
- 使用Maven或JBoss Tools在Eclipse上添加JBoss AS 7模块
- 在Play Framework中使用Files.createSymbolicLink获取FileSystemException“客户端不拥有所需的权限”