赞
踩
在 Java 中,Set
是集合框架中的一种接口,它表示不允许包含重复元素的集合。Set
接口继承自 Collection
接口,它没有提供额外的方法,但是它保证了集合中不会包含相同的元素。Set
接口的主要实现类有 HashSet
、LinkedHashSet
、TreeSet
等。
Set
不保证元素的顺序,即元素不按照特定的顺序存储和访问。Set
中添加已经存在的元素,add
方法将返回 false
。采用多态的形式
- Set<String> set=new HashSet<>();
- Set<String> set=new LinkedHashSet<>();
- Set<String> set=new TreeSet<>();
和Collection接口的方法大概一致,以下列举部分
boolean add(E e) | 添加指定元素 |
boolean remove(Object o) | 移除指定元素 |
boolean contains(Object o) | 判断集合中是否存在指定的元素 |
int size() | 返回集合中元素的个数 |
boolean isEmpty() | 判断当前集合是否为空 |
void clear() | 清空集合中的元素 |
HashSet集合底层采取哈希表存储数据
注:哈希表是一种对于增删改查数据性能都较好的结构。
哈希表的组成:
- JDK8之前:数组+链表
- JDK8之后:数组+链表+红黑树
存储规则:
- 创建一个默认长度为16,默认加载因子为0.75的数组,数组名为table
- 根据元素的哈希值与数组长度计算出应存入的位置
- 判断当前位置是否为null,如果是null则存入
- 如果位置不为null,表示有元素,则调用equals方法比较属性值
- 比较结果如果一致:不存储;比较结果不一致,形成链表
- JDK8之前:新元素存入数组,老元素挂在新元素下面
- JDK8之后:新元素直接挂在老元素下面。当链表长度超过8,而且数组长度大于等于64时,自动转换为红黑树;如果集合存储的是自定义对象,必须要重写hashCode和equals方法(因为如果不重写,比较的就是对象的地址值,为false)。
HashSet集合底层采取哈希表存储数据,每个元素额外的多了一个双链表的机制记录存储的顺序
HashSet集合底层采取红黑树存储数据
方式一:默认排序/自然排序
(1)默认排序
- 对于数值类型:Integer,Double,默认按照从小到大的顺序进行排序
- 对于字符、字符串类型,按照字符在ASCII码表中的数字升序进行排序
测试数字的排序
/** * 测试数字的排序 */ public class TreeSetDemo { public static void main(String[] args) { Set<Integer> set=new TreeSet<>(); set.add(1); set.add(9); set.add(2); set.add(6); System.out.println(set); } }测试字符串的排序
/** * 测试字符串的排序 */ public class TreeSetDemo { public static void main(String[] args) { Set<String> set=new TreeSet<>(); set.add("ab"); set.add("ac"); set.add("aba"); set.add("c"); set.add("cdb"); set.add("bdddd"); System.out.println(set); } }(2)JavaBean类实现Comparable接口指定比较规则
public class Teacher implements Comparable<Teacher>{ private String name; private int age; public Teacher(String name, int age) { this.name = name; this.age = age; } public int getAge() { return age; } @Override public String toString() { return "Teacher{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override public int compareTo(Teacher o) { System.out.println("this:"+this+",o:"+o); System.out.println("---------------------------"); return this.getAge()-o.getAge(); } }此处就重写了一个方法compareTo
o:红黑树中的元素
this:即将要插入的元素
return:
- 0:当前要添加的元素已存在,不添加
- 负数:当前要添加的元素是小的,添加到红黑树的左子树
- 正数:当前要添加的元素是大的,添加到红黑树的右子树
import java.util.Set; import java.util.TreeSet; public class TreeSetComparable { public static void main(String[] args) { Teacher t1 = new Teacher("张三", 23); Teacher t2 = new Teacher("李四", 24); Teacher t3 = new Teacher("王五", 20); Teacher t4 = new Teacher("赵六", 24); Set<Teacher> set = new TreeSet<>(); set.add(t1); set.add(t2); set.add(t3); set.add(t4); System.out.println(set); } }
默认使用第一种,如果第一种不能满足当前需求,就使用第二种
方式二:比较器排序
import java.util.Comparator; import java.util.TreeSet; public class TreeSetComparator { public static void main(String[] args) { TreeSet<String> set=new TreeSet<>(new Comparator<String>() { @Override public int compare(String o1, String o2) { //按照长度排序 int i=o1.length()-o2.length(); //如果长度一致则按照首字母排序 i=i==0?o1.compareTo(o2):i; return i; } }); set.add("hello"); set.add("helle"); set.add("holle"); set.add("to"); set.add("java"); System.out.println(set); } }注:返回值和上述方式1一致,此处的compareTo是String的方法。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。