1.Set接口
一个不包含重复元素的collecyion。更确切的讲,set不包含满足e1.equals(e2)的元素e1和e2,并且最多包含一个null元素。
2.HashSet
类实现Set接口,由哈希表(实际上是一个HashMap实例)支持。它不保证set的迭代顺序:特别是它不保证该顺序恒久不变。此类允许使用null元素。
package com.vince; import java.util.HashSet; import java.util.Set; public class SetDemo { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub HashSetDemo(); } /** * 1.不允许重复值(通过equals方法来判断) * 添加元素时如何判断是否重复,先调用对象的hashCode方法求值,如果hash值在集合中不存在,那么该对象可以添加(不重复的), * 如果hash值相同,(还不能确定对象是否相同,因为不同的对象可能产生相同的hashCode值),那么需要再调用equals方法来验证, * * 如果需要在程序中有这样的需求,两个对象的值相同就认为两个对象是一个对象,并且使用了HashSet来存储,就需要重写对象(类) * 中的hashCode方法和equals方法
*
*不保证遍历的顺序恒久不变
*基于HashMap实现 */ public static void HashSetDemo(){ System.out.println("----------"); Set<String> set=new HashSet<String>(); set.add("小明"); set.add("小花"); set.add("小明"); System.out.println(set.size());//输出的是2,因为不能为重复值 System.out.println("----------"); Set<Student> set2=new HashSet<Student>(); Student stu1=new Student("小刚",16); Student stu2=new Student("小花",23); Student stu3=new Student("小刚",16); set2.add(stu1); set2.add(stu2); set2.add(stu3);//虽然stu1和stu3的值相同,但是创建了两个内存空间,如果要让stu1和stu3代表同一个对象,则需要重写Student类中的equals方法 set2.add(stu1);//重复值了,所以不输出 System.out.println(set2.size()); System.out.println("----------"); } }
3.TreeSet
基于TreeMap的NavigableSet实现。使用元素的自然顺序对元素进行排序,或者根据创建set时提供的Comparator进行排序,具体取决于使用的构造方法。
4.LinkedHashSet
具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现。此实现与 HashSet 的不同之外在于,后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,即按照将元素插入到 set 中的顺序(插入顺序)进行迭代。注意,插入顺序不 受在 set 中重新插入的 元素的影响。(如果在 s.contains(e) 返回 true 后立即调用 s.add(e),则元素 e 会被重新插入到 set s 中。)
public class TreeSetDemo { /** * @param args */ public static void main(String[] args) { // TODO 自动生成的方法存根 TreeSet(); linkedHashSet(); } /** * 基于TreeMap实现 * 注意,在TreeSet集合中添加自定义对象,必须实现Comparable接口, * 因为添加方法会使用compareTo方法来验证对象的排序位置,并验证 * 对象是否重复(如果compareTo返回0,表示两个对象重复),不同的话,使用 * 大小来决定排序的顺序 * * 自然顺序对元素进行排序(从小到大) */ public static void TreeSet(){ Set<String> set=new TreeSet<String>(); set.add("小明"); set.add("小花"); set.add("小明"); System.out.println(set.size());//输出的是2,因为不能为重复值 System.out.println("----------"); Set<Student> set2=new TreeSet<Student>(); Student stu1=new Student("小刚",16); Student stu2=new Student("小花",23); Student stu3=new Student("小刚",16); set2.add(stu1); set2.add(stu2); set2.add(stu3); set2.add(stu1); System.out.println(set2.size()); System.out.println("----------"); } /** * 从HashSet继承而来,确保对象的插入顺序(其实就是与HashSet的区别) * 由双向链表+HashMap表实现 */ public static void linkedHashSet(){ Set<String> set=new LinkedHashSet<String>(); set.add("小明"); set.add("小花"); set.add("小明"); System.out.println(set.size());//输出的是2,因为不能为重复值 System.out.println("----------"); Set<Student> set2=new LinkedHashSet<Student>(); Student stu1=new Student("小刚",16); Student stu2=new Student("小花",23); Student stu3=new Student("小刚",16); set2.add(stu1); set2.add(stu2); set2.add(stu3); set2.add(stu1); System.out.println(set2.size()); System.out.println("----------"); } }
public class Student implements Comparable<Student> { String name; int 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; } public Student(String name, int age) { super(); this.name = name; this.age = age; } public Student() { super(); // TODO 自动生成的构造函数存根 } @Override public String toString() { return "Student [name=" + name + ", age=" + age + "]"; } @Override public int compareTo(Student o) { // TODO 自动生成的方法存根 if(age<o.age){ return -1; }else if(age>o.age){ return 1; } return 0; } }