java - 由于逻辑错误,允许相同的树集值
问题描述
大家好,我现在正在学习 java 集合并有这个任务。我的逻辑有问题,谁能告诉我我哪里出错了?这是我的代码。
这是我实例化母亲树集的家庭类
import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;
public class Family {
Mother mom = new Mother("0", 0, 0);
Set<Mother> Mothers = new TreeSet<Mother>(new Comparator<Mother>() {
public int compare(Mother a, Mother b) {
if(a.getName().compareTo(b.getName()) == 0) return 0;
if(a.getMonth() == b.getMonth()){
if(a.getDay() > b.getDay()) return 1;
else if(a.getDay() < b.getDay()) return -1;
}
if(a.getMonth() > b.getMonth()) return 1;
if(a.getMonth() < b.getMonth()) return -1;
return a.getName().compareTo(b.getName());
}
});
public Family(){}
public boolean addMother(java.lang.String name, int day, int month)
{
Mother a = new Mother(name, day, month);
return Nieces.add(a);
}
}
这是我分配母亲 TreeSet 的主类。
public class Main {
public static void main(String[] args) {
Family myFam = new Family();
myFam.addMother("Tokyo", 1, 3);
myFam.addMother("Shaline", 1, 1);
myFam.addMother("Betty", 2, 3);
myFam.addMother("Amy", 1, 1);
myFam.aaddMother("Shaline", 4, 3);
System.out.println(myFam.Mothers);
}
}
所以我想按日期和月份对其进行排序。我得到的输出是:[Amy, Shaline, Tokyo, Betty, Shaline] 这是正确的,因为它是根据日期和月份排序的,但我预计它只会是一个 Shaline因为它是一个树集。我该怎么做才能输出:[Amy, Shaline, Tokyo, Betty]。我也已经试过了if(a.getName().equals(b.getName())) return 0;
但它仍然无法正常工作。谢谢您的帮助!
解决方案
您的比较器不一致。请参阅比较器的合同:
实现者还必须确保关系是可传递的:
((compare(x, y)>0) && (compare(y, z)>0))
蕴含compare(x, z)>0
。
您的比较器违反了这一点,例如 when x
is"Shaline", 1, 1
和y
is "Betty", 2, 3
,它正在报告z
并使用月份或日期,因此传递性规则将要求,但由于名称相同,您的比较器通过返回零来报告。"Shaline", 4, 3
x < y
y < z
x < z
x == z
依赖于传递性,TreeSet
因为它允许有效查找,通过不将每个元素与插入时的新元素进行比较,而是使用顺序导航到树中的正确位置。
您可以添加一个线性搜索,就像在这个答案中一样,但这会降低效率,Set
因为它现在比较每个包含的元素。
相反,我推荐类似的东西:
Set<String> names = new HashSet<>();
Set<Mother> mothers = new TreeSet<>(Comparator.comparingInt(Mother::getMonth)
.thenComparingInt(Mother::getDay).thenComparing(Mother::getName));
public Family(){}
public boolean addMother(java.lang.String name, int day, int month)
{
return names.add(name) && mothers.add(new Mother(name, day, month));
}
这简化并修复了比较器,它现在始终使用Mother
对象的所有属性并添加了有效的预测试。
推荐阅读
- amazon-web-services - Powershell 写入 AWS S3
- reactjs - 为什么要在升级 Material UI 时升级 React
- mysql - 来自 MySQL 数据库的查询在 node.js 和 JSON.stringify() 中返回 [Object] [Object] 似乎不起作用
- docker - Docker如何将文件复制到Windows?
- python - 为什么 Best First search Python 实现没有给出正确的输出
- reactjs -
不显示反应中的组件 - c - 为什么我得到这个程序的错误输出?
- c# - 在 UAC OFF 的情况下在具有特权提升的子进程中启动 Windows 服务
- sorting - 如何使用比较器对一组双端队列进行排序
- python - 如何在python pymysql中获取一列数据