java中Set集合
/** * 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()); } }