Hash表和数组表的比较,哈希表数据结构是按照元素的特征通过指定的功能算出该元素的位置,这种方式查找时候比较快,不 用去遍历整个数组,直接用要查找的数据进行元素即可,存入其他的数据类型也可以,比如说字符串,只要定义一个功能算法对其进行运算即可,
注意:哈希值冲突,比如31%10和21%10最后的值都是1,只是往1角标中存储就冲突了,怎么去解决这个问题呢?哈希表有种特殊的方式:再散列方式(就是再把这个数据进行取模,算出其他的位置),除此之外还有另外一种方式:当算到相同的值时,就在该冲突的位置的基础上向下顺延一个位置出来,这时候便不再冲突了,如过还有值冲突就继续向下顺延,上图结构通过equals方法来判断对象是否想用,这个方法只有在哈希值一样的时候才会用到。
实现代码:
需求:存储自定义对象,比如Person,同姓名和同年龄视为同一个人,是相同元素。
hashSet hs=new hashSet();
Hs..add(new Person("lisi1",20));
Hs..add(new Person("zhangsan",20));
Hs..add(new Person("wangwu",20));
Hs..add(new Person("sunba",20));
Hs..add(new Person("zhangsan",20));
取出来
Iterator it=hs.iterator();
While(it.hasNext())
{
Person p=(Person)it.next();
Sop(p.getName()+p.getAge());
}
Class Person()
{
Private String name;
Private int age;
Person(String name,int age)
{
This.name=name;
This.age=age;
}
Public void setName(String name){
This.name=name;
}
Public void getName()
{
Return name;
}
Public void setAge(){
This.age=age;
}
Public int getAge()
{
Return age;
}
Public String toString(){
Return "Person:"+name+"::"+age;
}
定义一个比较方式,按照年龄进行自然排序
Public int compareTo(Object o){
Person p=(Person)o;
Int temp=this.age-p.age;
Return temp==0?this.name.compareTo(p.name):temp;
/**按照姓名进行自然排序
Int temp=this.name.compareTo(p.name){
Return temp=-0?this,.age-p.age:temp;
}
*/
}
覆盖hashCode()方法
Public int hashCode(){
Final int NUMBER=28;//为什么要定义常量,是因为避免哈希值冲突的情况,比如说一个姓名取哈希值为20,年龄取哈希值为40.另外一个人的姓名取哈希值为40年龄哈希值为20;两个的和都是60,用它进行哈希运算,可能得到的值都是相同的,这样的话再哈希结构表中的数据存储都是冲突的。所以才定义这样一个常量类避免这种冲突。
Return name.hashCode()+age*NUMBER;
}
覆写equals方法其实就是建立对象自身特有的判断对象是否相同的依据。
Public boolean equals(Object o){
If(!(Obj instanceof Person))
Throw new ClassCastException("数据错误"):
Person p=(Person)obj;
Return this.name.equals(p,.name)&&this.age==p.age;
}
}
|--TreeSet:用于给Set集合中的元素按照指定的顺序进行排序,低层是二叉树数据结构,线程是不同步的。
如何保证元素的唯一性呢?就是用过元素对象的比较方法返回值来确定的,如果为0,视为两个元素为相同的元素,不存储。
两种排序方式:
1、让元素自身具备比较功能,就是强制让元素去实现comparable接口,覆盖compareTo方法。这时元素具备的自然排序。可是如果元素自身不具备比较的功能,获取具备的比较功能不是所需要的。这时该排序方式就不能用了。
2、让集合自身具备比较功能,需要定义比较器,其实就是将实现了Comparator接口的子类对象作为参数传递给TreeSet集合的构造函数,让treeSet集合一创建就具备了比较功能。该子类必须要覆盖compare方法。
二叉树数据结构分析:
Iterator it=ts.iterator();
While(it.hasNext()){
Person p=(Person)it.next();
Sop(p.getName()+p.getAge());
}
当元素自身没有比较功能的时候要定义实现Comparator接口的方法,让对象具备有比较功能,这时候要覆盖comparator接口的compare方法
实现代码:
Class ComparatorByName implements Comparator{
Public int compare(Object o1,Object O2){
Person p1=(Person)o1;
Person p2=(Person)o2;
Int temp=p1.getName().compareTo(p2.getName());
Return temp==0?p1.getAge()-p2.getAge():temp;
}
}
3、查阅集合的技巧
List
|--Vector
|--ArrayList
|--LinkedList
Set
|--HashSet
|--TreeSet
在JDk1.2集合框架出现后,名称的阅读性非常强,通过名称就可以识别。明确所属的子体系,只要看后罪名,到底具体这个集合是什么结构,有什么特点,只要看前缀即可。
看到Array:数组结构,就要想到角标,有序,可重复,查询快
看到link:链表结构,想到增删快,同时可以明确操作first last的方法、
看到hash:哈希表结构,就要想到无序,不可以重复,必须要想到元素依靠的hashCode和equals方法来保证唯一性。
看到Tree:二叉树,就要想到比较的功能和排序,必须要想到两个接口,Comparable--compareTo Comparator---compare
集合中常用的集合对象都是不同步的。