/**
* Set:元素不可以重复,是无序的
* Set接口中的方法和Collection一致
* Set有两个最重要的子类HashSet,TreeSet
* HashSet:内部数据哈希表,是不同步的,它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变。此类允许使用 null 元素。
* 如何保证该集合的元素唯一性呢?
* 是通过对象的hashCode()和equals()方法来完成对象唯 一性的
* 如果对象的hashCode()值不同,那么不用判断equals方法,就直接存储到哈希表中
* 如果对象的hashCode值相同,那么要再次判断对象 的equals方法是否为true
* 如果为true,视为相同元素,不存。如果为false,那么视为不同元素,就进行存储。
*
* 记住:如果元素要存储到HashSet集合中,必须覆盖hashCode方法和equals方法。
* 一般情况 下,如果定义的类会产生很多对象 ,比如 人,学生,书,通常都 需要覆盖equals,hashCode方法。
* 建立对象判断是否相同的依据
* TreeSet:可以对Set集合中的元素进行指定顺序的排序。是不同步 的。
* 判断元素唯一性的方式 :就是根据比较方法comperTo(),返回结果是否是0,是0,就是相同元素,则不往里存储
*
* TreeSet对元素进行排序的方式 一:
* 让元素自身具备比较功能,元素需要实现 Comparable接口,重写compeareTo方法
* 如果不要按照对象中具备 的自然顺序进行排序,如果对象 中不具备 自然顺序,怎么办?
* 可以使用TreeSet集合第二种排序方式 二:
* 让集合自身具备比较功能,定义一个类实现 Comparator接口,重写compare方法
* 将该 类对象作为参数传递给TreeSet集合的构造函数
* * LinkedHashSet是HashSet的子类,它是有序的,且不可重复 *///arrayList判断元素是否相同 remove(),contains(),的依据是equals()方法,//HashSet的依据是hashCode()和equals()方法,该元素是否有和该容器中的元素相同//所以对于自定义对象,如果利用ArrayList容器进行存储,一定要重写equals()方法,//所以对于自定义对象,如果利用HastSet容器进行存储,一定要重写HashCode()和equals()方法,//往HashSet集合中存储Person对象,如果姓名和年龄相同,视为同一个人,视为相同元素
public class Person implements Comparable {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public int hashCode() {//判断hash值是否相同
// System.out.println(this+"......hashcode...");
return name.hashCode() + age;
}
@Override
public boolean equals(Object obj) {//判断内容是否相同
if (this == obj) {
return true;
}
if (!(obj instanceof Person)) {
throw new ClassCastException("类型转换错误");
}
// System.out.println(this + "......equals...." + obj);
Person person = (Person) obj;
return this.name.equals(person.name) && this.age == person.age;
}
@Override
public String toString() {
return name + ":" + age;
}
@Override
public int compareTo(@NonNull Object o) {
Person person = (Person) o;
//主要是按年龄排序,如果年龄相同,根据姓名进行自然排序
int temp = this.age - person.age;
return temp == 0 ? this.name.compareTo(person.name) : temp;
}
}
//HashSetDemo public class HashSetDemo {
public static void main(String[] args) {
HashSet hashSet = new HashSet();
//下面使用LinkedHashSet,它是有序的,不可重复的
// HashSet hashSet = new LinkedHashSet();
hashSet.add(new Person("aaa", 10));
hashSet.add(new Person("bbb", 20));
hashSet.add(new Person("bbb", 20));
hashSet.add(new Person("ccc", 30));
hashSet.add(new Person("ccc", 30));
Iterator iterator = hashSet.iterator();
while (iterator.hasNext()) {
Person person = (Person) iterator.next();
System.out.println(person.getName() + "," + person.getAge());
}
}
}//TreeSetDemo
public class TreeSetDemo {
public static void main(String[] args){
demo1();
demo2();
}
//存自定义对象
private static void demo2() {
TreeSet treeSet = new TreeSet();
treeSet.add(new Person("zhangsan", 10));
treeSet.add(new Person("lisi", 20));
treeSet.add(new Person("wangwu", 20));
treeSet.add(new Person("wangwu", 20));
treeSet.add(new Person("zhaoliu", 30));
treeSet.add(new Person("zhouqi", 30));
Iterator iterator = treeSet.iterator();
while (iterator.hasNext()) {
Person person = (Person) iterator.next();
System.out.println(person.getName() + "," + person.getAge());
}
}
//存字符串
private static void demo1() {
TreeSet treeSet = new TreeSet();
treeSet.add("aaa");
treeSet.add("nbb");
treeSet.add("ecc");
treeSet.add("gcc");
treeSet.add("kdd");
Iterator iterator = treeSet.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
//方式 二 Comparator的运用,它的原理是二叉树
* 创建了一个根据Person类的name进行排序的比较器
*/
public class ComparatorByName implements Comparator {
@Override
public int compare(Object o, Object t1) {
Person person = (Person) o;
Person person1 = (Person) t1;
int temp = person.getName().compareTo(person1.getName());
return temp == 0?person.getAge()-person1.getAge():temp;
// return 1;//这样是有序排,怎么存,怎么取
// return -1;//这样是有序排,怎么存,反过来取
}
}
//下面是运用自定义比较器,存自定义对象
private static void demo2() {
TreeSet treeSet = new TreeSet(new ComparatorByName());//这样存进去Person类就不用实现Comparable接口
treeSet.add(new Person("zhangsan", 10));
treeSet.add(new Person("lisi", 20));
treeSet.add(new Person("wangwu", 20));
treeSet.add(new Person("wangwu", 20));
treeSet.add(new Person("zhaoliu", 30));
treeSet.add(new Person("zhouqi", 30));
Iterator iterator = treeSet.iterator();
while (iterator.hasNext()) {
Person person = (Person) iterator.next();
System.out.println(person.getName() + "," + person.getAge());
}
}
//对字符串长度进行比较排序
public class ComparatorByLength implements Comparator {
@Override
public int compare(Object o, Object t1) {
String s1 = (String) o;
String s2 = (String) t1;
int temp = s1.length()-s2.length();
return temp==0?s1.compareTo(s2):temp;
}
}
//运用字符串长度进行比较排序 存字符串
private static void demo1() {
TreeSet treeSet = new TreeSet(new ComparatorByLength());
treeSet.add("aaa");
treeSet.add("nbbdd");
treeSet.add("ecdc");
treeSet.add("gcad");
treeSet.add("kdeterfd");
Iterator iterator = treeSet.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}