关于java中TreeSet类的一些问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于java中TreeSet类的一些问题相关的知识,希望对你有一定的参考价值。

根据api文档中对于TreeSet类的解释,TreeSet(Comparator<? super E> comparator) ,定义一个TreeSet含参类时,其中比较器Comparator<? super E> comparator的类型下限是E,也就是可以传入E和E的父类。
但是在实际中比较器定义为Person,传入Worker可以正常编译。反之则不行,这不是和定义相反吗?
附上测试代码:
import java.util.*;

public class GenericDemo3

public static void main(String[] args)

TreeSet<Worker> ts = new TreeSet<Worker>(new comp());
ts.add(new Worker("wor1"));
ts.add(new Worker("wor2"));
ts.add(new Worker("wor3"));
Iterator<Worker> it = ts.iterator();
while (it.hasNext())
System.out.println(it.next().getName());




class Worker extends Person
Worker(String name)
super(name);



class comp implements Comparator<Person>
public int compare(Person p1, Person p2)
return p1.getName().compareTo(p2.getName());


参考技术A 范型E是TreeSet的类型参数,比较器的类型参数应该是TreeSet类型参数的父类
Person是比较器的类型参数,Worker是TreeSet的类型参数,Person是Worker的父类,所以没毛病

关于Java里的TreeSet判断重复元素。

一直没搞懂TreeSet是怎么判断重复元素的,有人说是先调用compareTo()方法,如果返回0,就判断为重复元素。于是我写了一个学生类,下面是各种方法
//重写hashCode()
public int hashCode()
return this.num.hashCode();

//重写equal()
public boolean equals(Object o)
Student stu = (Student)o;
if(this.num.equals(stu.num) == true)
return true;
else
return false;


//重写compareTo(T o)
@Override
public int compareTo(Student stu)
float thisAllScore = this.getChinese()+this.getMath()+this.getEnglish();
float stuAllScore = stu.getChinese()+stu.getMath()+stu.getEnglish();
if(this.hashCode() == stu.hashCode())
return 0;
else if(this.equals(stu) == true)
return 0;
else if(thisAllScore < stuAllScore)
return 1;
else if(thisAllScore > stuAllScore)
return -1;
else
return 1;


然后添加5个Student
Student stu1 = new Student("张三", "01", 85.0f, 92.0f, 97.0f);
Student stu2 = new Student("李四", "02", 78.0f, 95.5f, 87.0f);
Student stu3 = new Student("王五", "03", 89.0f, 80.5f, 93.0f);
Student stu4 = new Student("李六", "04", 96.5f, 82.5f, 83.0f);
Student stu5 = new Student("李六", "04", 196.5f, 82.5f, 83.0f);
allStu.add(stu1);
allStu.add(stu2);
allStu.add(stu3);
allStu.add(stu4);
allStu.add(stu5);

输出结果
-----------------排名-----------------
|1|04|李六|196.5|82.5|83.0|362.0|
|2|01|张三|85.0|92.0|97.0|274.0|
|3|03|王五|89.0|80.5|93.0|262.5|
|4|04|李六|96.5|82.5|83.0|262.0|
|5|02|李四|78.0|95.5|87.0|260.5|
stu4.getNum().hashCode() = 1540
stu5.getNum().hashCode() = 1540
stu4.equals(stu5) = true
stu4跟stu5的num的哈希码相同,equals返回true.
但是还是同时出现了,这是为什么呢
allStu 是一个TreeSet的名字。复制少了

set 维护的顺序(无论是否提供了显式比较器)必须与 equals 一致。(关于与 equals 一致 的精确定义,请参阅 Comparable 或 Comparator。)这是因为 Set 接口是按照 equals 操作定义的,但 TreeSet 实例使用它的 compareTo(或 compare)方法对所有元素进行比较,因此从 set 的观点来看,此方法认为相等的两个元素就是相等的。
好吧,我承认复制了API。不过上面说得很清楚,compareTo()返回0才是被认为两个元素是相等吧。
参考技术A 很简单,这个问题其实很简单,判断是不是重复对象,应该判断他的所有属性是否一样,不单单是hashCode而已。 参考技术B 因为TreeSet需要排序而HashSet不需要,空的无法排序

以上是关于关于java中TreeSet类的一些问题的主要内容,如果未能解决你的问题,请参考以下文章

Java关于一个java.util.TreeSet的问题

TreeSet类的排序问题

Java中TreeSet操作的计算复杂度?

201671010139 徐楠 关于学习方面的一些疑惑

关于 Java 中私有静态嵌套类的合成访问器的 Eclipse 警告?

Scala 的 TreeSet 与 Java 的 TreeSet - 民意调查?