---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------
hashSet:底层数据结构是哈希表
如何理解哈希表,什么是哈希表:每个对象都有一个哈希值,存储的位置就是按照哈希值来存的,并不是按照存进去的先后次序存放位置,哈希表存储的是对象的内存地址
去除重复元素的内部实现原理
首先每个对象内部都从Object处继承了hashCode(),可以计算自己的哈希值,判断两个对象是否相等的机制,可以通过比较两个对象的哈希值,也可以通过equals()
对于List(ArrayList、LinkedList)比较对象:
依赖equals(),只通过equals()进行比较,通过返回值来确定对象是否相同,可以重写对象的equals()方法,为List元素实现不同的排序
注意一个细节:重写的特点,被覆写的方法的名称,参数,返回值类型要完全一致,对象的equals()是继承Object类的,所以equals接收的参数应该是Object,equals(Object obj),要得到对象后应该要强转,如果使用了泛型,则可以避免强转
但是!!!
对于hashSet比较对象:
首先比较hashCode(),如果hashCode()值不同,直接返回false,不会调用equals()
只有当hashCode()值相同时,才会调用equals()比较自定义的标准
对于TreeSet比较对象
对象通过compareTo();与hashCode()和equals()无关
TreeSet存储的一个特点(TreeSet的内部存储结构是二叉树)
在存进去的时候,就已经按照排序规则,排好序,所以取出的值是已经排好序了的,并且也已经去除了重复元素,TreeSet去除重复元素的原理和hashSet是不相同的,判断的方法不是根据hashCode,也不是equals,而是compareTo(),实现comparable接口,覆写compareTo方法
示例:
TreeSet a = new TreeSet();
a.add("dsfsd");
a.add("kjhdfs");
a.add("dgbs");
a.add("ass");
a.add("zxcvb");
Iterator it = a.iterator();
while(it.hasNext())
{
System.out.println(it.next());
}
输出结果是:
ass
dgbs
dsfsd
kjhdfs
zxcvb
上述的对象是String类型的,而String已经实现了comparable这个接口,所以,String类型的对象是具备比较性的
对于存储的对象,如果要把对象存储进TreeSet中,有两种解决方法
第一:让对象具备比较性,具备比较性才允许存储进TreeSet集合当中,否则,编译会报错
所以,要让对象具备比较性,就要让类去实现comparable这个接口,并且覆写里面的compareTo()方法
TreeSet集合在存储的过程中,会自动排除重复元素
判断的方法不是根据hashCode,也不是equals,而是compareTo
TreeSet的内部数据结构是二叉树,二叉树也称为红黑树,存储时依次比较
二叉树的特点:左小右大
有个问题不理解
视频中说,当元素很多的时候,会取中间值开始比较,存储效率是提高了,但是这个就不再是一个严格的顺序了,就成为一个相对的顺序了,这是为什么?
答:选取中间值作为二叉树的根节点,并没有改变二叉树的存储机制。其实只是对二叉树做了一个变形而已
第二:当元素不具备比较性时,需要让集合自身具备比较性
这个怎么理解?集合它本身也不具备比较的功能,但是TreeSet有一个构造方法可以传入一个比较器,TreeSet(comparator T)就相当于说,TreeSet想干某件事,但是缺少这么干这件事的工具,现在我自己做了一个工具,把它给了集合,那么此时TreeSet就可以用这个工具去做这件事了
创建一个比较器类,实现comparator接口,并且覆盖compare方法,compare(Object obj1,Object obj2)
用法示例:
TreeSet t1 = new TreeSet(new myCompare())//传入一个比较器给集合使用
……………………………省略
Public class myCompare implements comparator
{
Public int compare(Object obj1,Object obj2)//覆写compare
{
具体的比较语句
}
}
总结:
当存在两种比较方法的时候,以比较器为主
附:
Comparable是让对象具备比较性的时候用到,对象类实现该接口,然后覆写compareTo()
comparator()是创建比较器的时候要用到,比较器类实现该接口,然后覆写compare()
int compareTo()和int compare方法的区别:
int compareTo()是接口comparable里的方法
int compare()是接口comparator里的方法
两者的内部的比较方式都一样:比较此对象与指定对象的顺序。如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数
---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------