Set 集合
Set 接口 (无序,元素不能重复),继承了 Collection 接口无特有方法。
Set 已实现类与特性:
- HashSet:哈希表结构,保证元素唯一性依靠 
hashCode() 和 equals() 方法(hash 值相同时再判断 equals,相同将不再存储),不同步 
- TreeSet:是链表结构(指针),需保证元素唯一性,可排序
 
- LinkedHashSet:HashSet 的子类,按存入顺序使用
 
Set 利用 Iterator 动态移除元素:
与 list 类似直接在 foreach 或循环中动态 add 或 remove 会出错。
1 2 3 4 5 6 7 8 9 10 11 12 13
   | Set set=new HashSet(); set.add("set0"); set.add("set1"); set.add("set2");
  Iterator iterator=set.iterator(); while (iterator.hasNext()){     String str = (String) iterator.next();     if (str.equals("set1")) {         iterator.remove();     }     System.out.println(str); }
   | 
 
HashSet 元素唯一性:
- HashSet 保证元素唯一性是通过元素的两个方法,hashCode()和 equals()来完成的。
 
- 如果元素的 HashCode 值相同,才会判断 equals 是否为 true。
 
- 如果元素的 HashCode 值不同,不会调用 equals。
 
由此可知我们要保证 Set 中存入的对象(元素)唯一时,需在该元素类中重写 hashCode 和 equals 方法。
例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
   | class stu{     private String name;     private int age;     public stu(String name, int age) {         this.name = name;         this.age = age; }     @Override     public int hashCode() {         return Objects.hash(name);     }     @Override     public boolean equals(Object o) {         stu stu = (stu) o;         return name.equals(stu.name);     }     @Override     public String toString() {return "stu{name="+name+"-age="+age+"}";} } --------------使用---------------------------- HashSet hashSet=new HashSet(); hashSet.add(new stu("stu1",10)); hashSet.add(new stu("stu2",30)); hashSet.add(new stu("stu1",20)); System.out.println(hashSet);
  | 
 
运行结果:
[stu{name=stu1-age=10}, stu{name=stu2-age=30}]
可以看出因为 new stu("stu1",10) 即 stu1 已存在 new stu("stu1",20) 存入失败。
TreeSet 排序与去重:
- TreeSet 保证元素唯一性和排序依靠,
Comparable 接口的 compareTo 或 Comparator 接口的 compare方法。此 
- new TreeSet 时传入一个 Comparator 对象,将使用此接口方法比较元素。
 
- 不传入参数时默认需元素类实现 Comparable 接口,将默认使用此接口 compareTo 方法,来比较元素。存入的元素类未实现此接口将报错。
 
- 比较元素时返回值 等于 0 表示 元素重复。
 
使用默认比较排序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
   |  class stu implements Comparable{     private String name;     private int age;     public stu(String name, int age) {         this.name = name;         this.age = age; }     @Override     public String toString() {return "stu{name="+name+"-age="+age+"}";}     @Override     public int compareTo(Object o) {         stu s=(stu)o;         return name.compareTo(s.name);     } } ----------------使用------------------- TreeSet hashSet=new TreeSet(); hashSet.add(new stu("stu1",10)); hashSet.add(new stu("stu2",30)); hashSet.add(new stu("stu1",20)); System.out.println(hashSet);
 
  | 
 
运行结果:
[stu{name=stu1-age=10}, stu{name=stu2-age=30}]
使用比较器比较排序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
   |  class compare implements Comparator{         @Override     public int compare(Object o1, Object o2) {         stu s1=(stu) o1;         stu s2=(stu) o2;         return s1.name.compareTo(s2.name);     } } ------------------使用-----------------------------
  TreeSet hashSet=new TreeSet(new compare()); hashSet.add(new stu("stu1",10)); hashSet.add(new stu("stu2",30)); hashSet.add(new stu("stu1",20)); System.out.println(hashSet);
 
  | 
 
运行结果与上同。
Set 中有序集合 LinkedHashSet:
1 2 3 4 5
   | LinkedHashSet hashSet=new LinkedHashSet(); hashSet.add(new stu("stu1",10)); hashSet.add(new stu("stu2",30)); hashSet.add(new stu("stu1",20)); System.out.println(hashSet);
   | 
 
运行结果:
[stu{name=stu1-age=10}, stu{name=stu2-age=30}]
LinkedHashSet 去重与 HashSet 同,元素顺序与存入时的顺序同。