Set接口

Set接口

存储无序、不可重复的数据

以Hashset为例说明

  1. 无序性:不等于随机性。存储的数据在底层数组中并非按照数组索引的顺序添加,而是根据数据的哈希值决定
  2. 不可重复性:保证添加的元素按照equals()判断时,不饿能返回true.即:相同元素只能添加一个。
  3. 向HashSet中添加元素a,首先调用元素a所在类的hashCode()方法,计算元素a的哈希值,此哈希值接着通过某种算法计算出在HashSet底层数组中的存放位置(即为:索引位置),判断此位置上是否以及有元素。如果此位置上没有元素,则元素a添加成功。如果此位置上有其他元素b(或以链表形式存在多个元素),则比较元素a与元素b的hash值:如果hash值不相同,则元素a添加成功。如果hash值相同,进而调用元素a的equals()方法;equals()返回true,元素a添加失败。否则,元素a添加成功。

TreeSet是 SortedSet接口的实现类,TreeSet可以确保集合元素处于排序状态。

TreeSet底层(数组+链表)使用 红 黑 树 \textcolor{Red}{红黑树} 结构存储数据

  • 新增的方法如下:(了解)
    • C o m p a r a t o r \textcolor{Red}{Comparator} Comparator c o m p a r a t o r ( ) \textcolor{Red}{comparator()} comparator()
    • O b j e c t \textcolor{Red}{Object} Object f i r s t ( ) \textcolor{Red}{first()} first()
    • O b j e c t \textcolor{Red}{Object} Object l a s t ( ) \textcolor{Red}{last()} last()
    • O b j e c t \textcolor{Red}{Object} Object l o w e r ( O b j e c t \textcolor{Red}{lower(Object} lower(Object e ) \textcolor{Red}{e)} e)
    • O b j e c t \textcolor{Red}{Object} Object h i g h e r ( O b j e c t \textcolor{Red}{higher(Object} higher(Object e ) \textcolor{Red}{e)} e)
    • S o r t e d S e t \textcolor{Red}{SortedSet} SortedSet s u b S e t ( f r o m E l e m e n t , t o E l e m e n t ) \textcolor{Red}{subSet(fromElement, toElement)} subSet(fromElement,toElement)
    • S o r t e d S e t \textcolor{Red}{SortedSet} SortedSet h e a d S e t ( t o E l e m e n t ) \textcolor{Red}{headSet(toElement)} headSet(toElement)
    • S o r t e d S e t \textcolor{Red}{SortedSet} SortedSet t a i l S e t ( f r o m E l e m e n t ) \textcolor{Red}{tailSet(fromElement)} tailSet(fromElement)
  • TreeSet两种排序方法: 自 然 排 序 \textcolor{Red}{自然排序} 定 制 排 序 \textcolor{Red}{定制排序} 。默认情况下,TreeSet采用自然排序。

实现类之一:HashSet

HashSet是 Set接口的典型实现,大多数时候使用Set集合时都使用这个实现类。

HashSet按 Hash 算法来存储集合中的元素,因此具有很好的存取、查找、删除性能。

H a s h S e t 具 有 以 下 特 点 : \textcolor{Red}{HashSet具有以下特点:} HashSet:

  • 不能保证元素的排列顺序
  • HashSet不是线程安全的
  • 集合元素可以是 n u l l \textcolor{Red}{null} null

H a s h S e t 集 合 判 断 两 个 元 素 相 等 的 标 准 : \textcolor{Red}{HashSet集合判断两个元素相等的标准:} HashSet:两个对象通过 hashCode()方法比较相等,并且两个对象的equals()方法返回值也相等。

对于存放在Set容器中的对象, 对 应 的 类 一 定 要 重 写 e q u a l s ( ) 和 h a s h C o d e ( O b j e c t o b j ) 方 法 , 以 实 现 对 象 相 等 规 则 。 即 : “ 相 等 的 对 象 必 须 具 有 相 等 的 散 列 码 ” 。 \textcolor{Red}{对应的类一定要重写equals()和hashCode(Objectobj)方法,以实现对象相等规则。即:“相等的对象必须具有相等的散列码”。} equals()hashCode(Objectobj):

import org.junit.Test;

import java.util.*;

/**
 * @创建人 HeXin
 * @所属包 SetTest
 * @所属项目 JavaSenior
 * @创建时间 2022/12/2 19:51
 * @描述
 */
public class SetTest {
/**
 *@BelongsProject: JavaSenior
 *@BelongsPackage: SetTest
 *@Author: HeXin
 *@CreateTime: 2022/12/2  19:51
 *@Description:
 *@Version: 1.0
 *
 */
    @Test
    public void test() {
        Set set = new HashSet();
        set.add(123);
        set.add(456);
        set.add(new String("WLM"));
        set.add(new String("LIKE"));
        set.add("WLM");
        set.add(new People("WLM",19));
        set.add(new People("WLM",20));
        Iterator iterator = set.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
    //LinkedHashSet的使用
    //LinkedHashSet作为HashSet的子类,在添加数据的同时,每个数据还维护了两个引用,记录此数据前一个数据和后一个数据
    //优点:对于频繁的遍历操作,LinkedHashSet效率高于HashSet
    @Test
    public void test1() {
        Set set = new LinkedHashSet();
        set.add(123);
        set.add(456);
        set.add(new String("WLM"));
        set.add(new String("LIKE"));
        set.add("WLM");
        set.add(new People("WLM",19));
        set.add(new People("WLM",20));
        Iterator iterator = set.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
    //1.向TreeSet中添加的数据,要求是像同类的对象。
    //两种排序方式:自然排序   和    定制排序
    //自然排序中,比较两个对象是否相同的标准为: compareTo( )返回0.不再是equals().
    //定制排序中,比较两个对象是否相同的标准为: compare()返回0.不再是equals().
    @Test
    public void test2() {

        //失败:不能添加不同类对象

//        TreeSet set = new TreeSet();
//        set.add(123);
//        set.add(456);
//        set.add(new String("WLM"));
//        set.add(new String("LIKE"));
//        set.add("WLM");
//        set.add(new People("WLM",19));
//        set.add(new People("WLM",20));

        //举例一:

//        TreeSet set = new TreeSet();
//        set.add(new String("WLM"));
//        set.add(new String("LIKE"));
//        set.add("CXY");
//        set.add("YJJ");

        //举例二:

        TreeSet set = new TreeSet();
        set.add(new People("WLM",19));
        set.add(new People("WLM",18));
        set.add(new People("ZJN",18));
        set.add(new People("YJJ",20));
        set.add(new People("WRT",22));
        Iterator iterator = set.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
    @Test
    public void test3() {
        Comparator comparator = new Comparator() {
            //按照年龄从小到大排序
            @Override
            public int compare(Object o1, Object o2) {
                //Java17新特性
//                if (o1 instanceof People p1 && o2 instanceof People p2) {
//                    return p1.getAge() - p2.getAge();
//                } else {
//                    throw new UnsupportedOperationException("输入的数据类型不匹配");
//                }
                if(o1 instanceof People&&o2 instanceof People){
                    People p1 = (People)o1;
                    People p2 = (People)o2;
                    return Integer.compare(p1.getAge(),p2.getAge());
                }else{
                    throw new RuntimeException("输入的数据类型不匹配!");
                }
            }
        };
        TreeSet set = new TreeSet(comparator);
        set.add(new People("WLM",19));
        set.add(new People("WLM",18));
        set.add(new People("ZJN",18));
        set.add(new People("YJJ",20));
        set.add(new People("WRT",22));
        Iterator iterator = set.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
}
class People implements Comparable{
    private String name;
    private int age;

    @Override
    public String toString() {
        return "People{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        People people = (People) o;

        if (age != people.age) return false;
        return Objects.equals(name, people.name);
    }

    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + age;
        return result;
    }

    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 People() {
    }

    public People(String name, int age) {
        this.name = name;
        this.age = age;
    }
    //按名字从小到大排列,年龄从小到大排列
    @Override
    public int compareTo(Object o) {
        if(o instanceof People){
            People people = (People) o;
            int  result = this.name.compareTo(people.name);
            if(result != 0){
                return result;
            }else{
                return Integer.compare(this.age, people.age);
            }
        }else{
            throw new RuntimeException("输入的类型不匹配!");
        }
    }
}

注:此文章为本人学习过程中的随手笔记,样式较为简陋,若有雷同,请见谅!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值