* Set子接口:元素是无序的(存入和取出的顺序不一定一致),元素是不可以重复的。
* |--HashSet:底层数据结构是哈希表。HashSet是如何保证元素的唯一性呢?
* | 是通过元素的两个方法,hashCode和equals来完成。如果两个元素的hashCode值相等,才会判断
* | equals是否为true。如果元素的hashCode值不同,那么就不会调用equals。
* | 注意:对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashCode和equals方法.
* |
* |--TreeSet:对Set集合中的元素的进行指定顺序的排序。不同步。TreeSet底层的数据结构就是二叉树。
哈希表的原理:
1,对对象元素中的关键字(对象中的特有数据),进行哈希算法的运算,并得出一个具体的算法值,这个值 称为哈希值。
2,哈希值就是这个元素的位置。
3,如果哈希值出现冲突,再次判断这个关键字对应的对象是否相同。如果对象相同,就不存储,因为元素重复。如果对象不同,就存储,在原来对象的哈希值基础 +1顺延。
4,存储哈希值的结构,我们称为哈希表。
5,既然哈希表是根据哈希值存储的,为了提高效率,最好保证对象的关键字是唯一的。
这样可以尽量少的判断关键字对应的对象是否相同,提高了哈希表的操作效率。
hashCode() 方法:
代码示例:
//Person类
class Person
{
//属性name
private String name;
//属性age
private int age;
//构造函数
public Person(String name, int age)
{
this.name = name;
this.age = age;
}
//重写hashCode方法
public int hashCode()
{
System.out.println(this.name+"--hashCode");
return name.hashCode()+age*37;
}
//重写equals方法
public boolean equals(Object obj)
{
//判断是否属于Person类型,如果不是直接返回false
if (!(obj instanceof Person))
return false;
//强转为Person类型
Person p = (Person) obj;
System.out.println(this.name+"--equals--"+p.getName());
//根据Person类型,定义自己独特的比较规则
return this.name.equals(p.getName()) && this.age == p.getAge();
}
//getName方法
public String getName()
{
return name;
}
//getAge方法
public int getAge()
{
return age;
}
}
TreeSet:可以对Set集合中的元素进行排序。底层数据结构是二叉树。保证元素唯一性的依据就是compareTo的return返回值。
* 后存入的元素调用compareTo方法并传入前面的元素进行比较,如果compareTo方法return返回正数就表示比前面元素大,
* 就存到了二叉树的右边,取出时是后取出该元素的。
* 如果return返回0,则两个元素一样,则不会存入。
* 如果return返回负数表示比前面元素小,就存在二叉树的左边,取出时会先取出该元素。
*
* TreeSet排序的第一种方式:让元素自身具备比较性。元素需要实现Comparable接口,重写compareTo方法。
* 这种方式也称为元素的自然顺序,也叫元素的默认顺序。
*
* TreeSet集合第二种排序方式:当元素自身不具备比较性或者具备的比较性不是所需要的,这时需要让集合自身具备比较性。
* 让集合一初始化就有了比较方式。定义比较器类,实现Comparator接口,重写compare()方法。
自然排序:
代码示例:
//学生类,实现了Comparable接口,该接口强制让学生具备比较性。
class Student implements Comparable
{
//name属性
private String name;
//age属性
private int age;
//构造函数
public Student(String name, int age)
{
this.name = name;
this.age = age;
}
//getName方法
public String getName()
{
return name;
}
//getAge方法
public int getAge()
{
return age;
}
//重写compareTo方法,当Student类的对象存入二叉树数据结构的集合,如TreeSet集合时,会根据此方法进行对象之间的比较
public int compareTo(Object obj)
{
//判断要比较的对象是否是学生类型,不是则直接抛出异常
if (!(obj instanceof Student))
throw new RuntimeException("不是学生对象!");
//强转为学生类型
Student s = (Student) obj;
//如果两个对象age值相同
if (this.age == s.age)
//则比较两对象的name值
return this.name.compareTo(s.name);
//返回两对象age值的比较结果
return this.age-s.age;
}
}
定制比较器:
import java.util.Comparator;
//定义一个比较器类
class MyCompare implements Comparator
{
//重写compare方法,比较o1和o2对象
public int compare(Object o1, Object o2)
{
//将o1对象和o2对象转换成Student类型
Student s1 = (Student) o1;
Student s2 = (Student) o2;
//如果两个对象的name属性相等时,就比较age属性值
if (s1.getName().compareTo(s2.getName()) == 0)
//返回两个对象的age属性值的比较结果
return s1.getAge() - s2.getAge();
// 返回两个对象name属性值的比较结果
return s1.getName().compareTo(s2.getName());
}
}
------- android培训、 java培训、期待与您交流! ----------