我有一个班级'CoAutoria',可以容纳2个“作者”类的实例(目前只有一个名字)以及这些作者的共同文章数量。
为了找出共同作者的前十名(关于文章数量),我创建了一个'CoAutoria'的TreeSet,用于保存每一对的文章总数。
我需要循环浏览多年的地图,收集不同的作者和他们各自的共同作者集。然后,为每对创建一个'CoAutoria'实例并:将其添加到树集中(如果它尚不存在);或者简单地将其文章数量与该集合中存在的文章数量相加。
我已经创建了compareTo方法,将其插入到树集上,并创建了equals方法,以便作者的顺序无关紧要。
这是主要代码:`
public class CoAutoria implements Comparable<CoAutoria>
{
private Autor autor1;
private Autor autor2;
private int artigosComum;
(...)
}
@Override
public int compareTo(CoAutoria a2)
{
String thisAutor1 = autor1.getNome();
String thisAutor2 = autor2.getNome();
String caAutor1 = a2.getAutor1().getNome();
String caAutor2 = a2.getAutor2().getNome();
if((autor1.equals(a2.getAutor1()) && autor2.equals(a2.getAutor2())) || (autor1.equals(a2.getAutor2()) && autor2.equals(a2.getAutor1())))
{
return 0;
}
else
{
return 1;
}
}
@Override
public boolean equals(Object o)
{
if(this == o)
{
return true;
}
if( o == null || o.getClass() != this.getClass())
return false;
CoAutoria ca = (CoAutoria) o;
String thisAutor1 = autor1.getNome();
String thisAutor2 = autor2.getNome();
String caAutor1 = ca.getAutor1().getNome();
String caAutor2 = ca.getAutor2().getNome();
if((thisAutor1.equals(caAutor1) && thisAutor2.equals(caAutor2)) || (thisAutor1.equals(caAutor2) && thisAutor2.equals(caAutor1)))
{
return true;
}
else
{
return false;
}
}
主要问题是:当我检查该集合是否已经具有某个'CoAutoria'实例时,(我正在使用TreeSet的contains()方法),它会给我错误的结果...有时它会正确检查对AB已经存在于该集合中(以BA的形式),但有时它不会...对于我所读到的,包含使用equals方法,因此不会发生这种情况。
[编辑:] 从第一篇文章开始,我开始认为问题可能存在于compareTo ..所以我将其改为
public int compareTo(CoAutoria a2)
{
String thisAutor1 = autor1.getNome();
String thisAutor2 = autor2.getNome();
String caAutor1 = a2.getAutor1().getNome();
String caAutor2 = a2.getAutor2().getNome();
if(this.equals(a2))
{
System.out.println("return 0");
return 0;
}
else
{
int aux = thisAutor1.compareTo(caAutor1);
if(aux != 0)
{
return aux;
}
else
{
return thisAutor2.compareTo(caAutor2);
}
}
}
但它仍然给我糟糕的结果......我想我现在已经想到了:如果它是相同的'CoAutoria',我返回0,如果不是我通过名称,并按照他们的compareTo值排序..但缺少一些东西
答案 0 :(得分:2)
您的contains
方法正在中断,因为您的compareTo
方法始终返回0或正数,没有负数。这意味着您的compareTo
不一致。如果作者相同,则正确的实现应返回0;如果作者不同,则应返回正和负值。
示例(假设author1
与author2
不同):
int i = author1.compareTo(author2); // i should be positive or negative
int j = author2.compareTo(author1); // j should be the opposite of i
对于上述两种情况,您将返回1
,这将使有序集合无效,因为任何元素都不会smaller
。另一个例子想象一下,如果你有一个二元树(有序集合),它有元素[1-10]。如果您正在搜索元素5,那么在将5与任何元素进行比较时,您的二叉树总是会说它等于或大于。
你应该如何改变它取决于你。但是一个想法是按名称对作者进行排序,然后迭代两个集合并按字典顺序将作者进行比较。
编辑:即使您对方法进行了编辑,它们仍然不一致。尝试以下方法,它们不是最有效的,但除非您真的想要优化速度,否则应该有效。请注意,他们首先排序以确保author1和author2在与另一个CoAutor
进行比较之前是有序的。我不做任何空检查,并假设两者都是有效的作者。
@Override
public boolean equals(Object o){
if (o == null || !(o instanceof CoAutoria)) return false;
if (o == this) return true;
return this.compareTo((CoAutoria)o) == 0;
}
@Override
public int compareTo(CoAutoria o) {
List<String> authors1 = Arrays.asList(autor1.getNome(), autor2.getNome());
List<String> authors2 = Arrays.asList(o.autor1.getNome(), o.autor2.getNome());
Collections.sort(authors1);
Collections.sort(authors2);
for (int i=0;i<authors1.size();i++){
int compare = authors1.get(i).compareTo(authors2.get(i));
if (compare != 0)
return compare;
}
return 0;
}