JavaSE(七)
六、Set接口
1、是什么
collection的子接口,Set接口的实现类常用的有:HashSet、TreeSet和LinkedHashSet。特点有:不可重复
2、常用方法
add(E e)如果set中尚未存在指定的元素,则添加此元素
clear()移除此set中的所有元素
contains(Object o)如果set包含指定的元素,则返回true
isEmpty()如果set不包含元素,则返回true
size()返回set中的元素数(其容量)
3、案例
package com.hg.Collection.Set;
import java.util.HashSet;
import java.util.Set;
public class SetTest {
public static void main(String[] args) {
Set<String> stringSet = new HashSet<>();
stringSet.add("hello");
stringSet.add("sister");
stringSet.add("叶瞬光");
stringSet.add("叶瞬光");
for (String s : stringSet) {
System.out.println(s);
}
System.out.println("长度为:" + stringSet.size());
System.out.println("是否为空:" + stringSet.isEmpty());
System.out.println("是否包含‘叶瞬光’:" + stringSet.contains("叶瞬光"));
stringSet.clear();
System.out.println(stringSet);
}
}
4、HashSet类
数据结构:底层采用了哈希表,哈希表的本质就是“数组+链表”
1.根据对象的哈希值计算(求余)存储位置,如果当前位置没有元素则直接存入;
2.如果当前位置有,则拿当前的元素和已经存在的元素比较哈希值,如果哈希值不同,则将当前元素进行存储;
3.如果哈希值相同则通过equals()方法比较两个元素的内容,如果内容不相同则将当前元素进行存储,如果内容相同则不存储当前元素。

案例:
package com.hg.Collection.Set.HashSet;
import java.util.HashSet;
import java.util.Set;
public class HashSetTest {
public static void main(String[] args) {
Set<Student> studentSet = new HashSet<>();
studentSet.add(new Student("叶瞬光",18));
studentSet.add(new Student("星见雅",18));
studentSet.add(new Student("仪玄",18));
studentSet.add(new Student("叶瞬光",18));
//没有重写hashCode和equals前Set会重复
//重写hashCode和equals后Set不会重复
for (Student student : studentSet) {
System.out.println(student);
}
}
}
class Student{
private String name;
private Integer age;
public Student() {
}
public Student(String name, Integer age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Student)) return false;
Student student = (Student) o;
if (!name.equals(student.name)) return false;
return age.equals(student.age);
}
@Override
public int hashCode() {
int result = name.hashCode();
result = 31 * result + age.hashCode();
return result;
}
}
5、LinkedHashSet类
概述:
LinkedHashSet是Set接口基于双向链表的实现,也是HashSet的子类。元素的存储和取出顺序是一致的。
数据结构:
LinkedHashSet根据元素的hashCode值来决定元素的存储位置,使用双向链表维护元素的次序,这使得元素看起来是以插入顺序保存的,如图:

LinkedHashSet的有序性本质是LinkedHashMap的特性,其核心逻辑简化如下:

案例:
package com.hg.Collection.Set.HashSet.LinkedHashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
public class LinkedHashSetTest2 {
public static void main(String[] args) {
//1.初始化一个空的 LinkedHashSet<String>;
Set<String> set = new LinkedHashSet<>();
//2.依次添加姓名:"张三"、"李四"、"王五"、"张三"、"赵六";
set.add("张三");
set.add("李四");
set.add("王五");
set.add("张三");
set.add("赵六");
//3.遍历并输出当前集合中的所有姓名(验证去重和有序性);
System.out.println("=============遍历==============");
for (String s : set) {
System.out.println(s);
}
//4.删除姓名 "李四",再次遍历输出;
System.out.println("=============删除后“李四”遍历==============");
set.remove("李四");
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()){
String s = iterator.next();
System.out.println(s);
}
//5.尝试删除不存在的姓名 "钱七",控制台打印 “删除结果:false”;
boolean res = set.remove("钱七");
System.out.println("删除结果:" + res);
//6.清空集合,遍历并打印 “集合为空”。
System.out.println("=============清空集合后遍历==============");
set.clear();
System.out.println("集合为空:" + set);
}
}
6、TreeSet类
概述:
TreeSet是Set接口基于红黑树的实现类;默认对元素进行自然排序;

数据结构:
/**
* 二叉树的节点类
* 用于描述二叉树中单个节点的结构,包含节点值、左子节点、右子节点
*/
public class TreeNode {
// 当前节点存储的数值
int val;
// 当前节点的左子节点 引用(指针),默认为null
TreeNode left;
// 当前节点的右子节点 引用(指针),默认为null
TreeNode right;
/**
* 二叉树节点的构造方法
* @param x 传入的当前节点的数值
*/
TreeNode(int x) {
// 给当前节点的数值赋值
val = x;
}
}
7、Comparable接口
TreeSet会调用集合元素的compareTo(Objectobj)方法来比较元素之间的大小关系,然后将集合元素按升序(默认情况)排列。
8、Comparator比较器
如果元素所属的类没有实现Comparable接口,或不希望按照升序(默认情况)的方式排列元素或希望按照其它属性大小进行排序,则考虑使用定制排序。
6、7、8、案例:
package com.hg.Collection.Set.TreeSet;
import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;
public class TreeSetTest2 {
public static void main(String[] args) {
Set<Student> studentSet = new TreeSet<>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.getAge() - o2.getAge();
}
});
studentSet.add(new Student("叶瞬光",18));
studentSet.add(new Student("星见雅",19));
studentSet.add(new Student("仪玄",20));
for (Student student : studentSet) {
System.out.println(student);
}
}
}
class Student /*implements Comparable<Student>*/{
private String name;
private Integer age;
public Student() {
}
public Student(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
/*@Override
public int compareTo(Student o) {
return this.age - o.age;
}*/
}
更多推荐




所有评论(0)