JavaSE---collection的子接口之二Set接口

1、Set接口概述,继承Collection接口的方法

在这里插入图片描述

Collection接口:单列集合,用来存储一个一个对象
 *      Set接口:存储无序的,不可重复的数据  ---->高中讲的“集合”
 *          HashSet:作为Set接口的主要实现类;线程不安全的,可以存储null*              LinkedHashSet:作为HashSet的子类,遍历器内部数据时,可以按照添加的顺序遍历。
 *                             对于频繁的遍历操作,LinkedHashSet效率高于HashSet
 *          TreeSet:可以按照添加对象的指定属性,进行排序。
 *
 *   1Set接口中没有额外定义新的方法,使用的都是Collection中声明过的方法
 *
 *   2、要求:向Set中添加的数据,其所在的类一定要重写hashCode()equals()
 *      要求:的hashCode()equals()尽可能保持一致性:相同的对象必须具有相同的散列码

1.1、Set接口的无序性证明

无序性指的是添加元素的时候,元素的存放位置并不是一个挨着一个存放的,而是没有顺序的存放的。
在这里插入图片描述

1.2、Set接口不可重复的

 Set:存储无序的、不可重复的数据
     *HashSet为例说明:
     * 1、无序性:不等于随机性。存储的数据结构在底层数组中并非按照数组索引的添加顺序添加、而是跟数组的哈希值。
     *
     * 2、不可重复性:保证添加的元素按照equals()判断时,不能返回true,即:相同的元素只能添加一个。
     *
     * 二、添加元素的过车:以HashSet为例:
     *     我们向HashSet中添加元素a,首先调用元素a所在类的hashCode()方法,计算元素a的哈希值,
     *     此哈希值接着通过某种算法计算出在HashSet底层数组中存放位置(即为:索引位置),判断
     *     数组此位置上是否已经有元素:
     *          如果此位置上没有其他元素,则元素a添加成功。--->情况1
     *          如果此元素位置上有其他元素b(或以链表形式存在的多个元素),则比较元素a与元素b的hash值::
     *              如果hash值不相同,则元素a添加成功。---->情况2
     *              如果hash相同,进而需要调用元素a所在类的equals()方法。
     *                  equals()返回true,元素a添加失败
     *                  equals()返回false,则元素a添加成功。--->情况3
     *     对于添加成功的情况2和情况3而言:元素a与已经存在指定索引位置上的数据以链表的方式存储。
     *     jdk7:元素a放到数组中,指向原来的元素
     *     jdk8:原来的元素在数组中,指向元素b
     *     HashSet底层:数组加链表

2、Set接口实现类之一HashSet

底层实现:数组+链表
在这里插入图片描述在这里插入图片描述
在这里插入图片描述

3、Set接口实现类之二LinkedHashSet

底层实现:数组+链表

  • LinkedHashSet作为HashSet的子类,在添加数据同时,每个数组还维护了两个引用,记录此数据前一个数据和后一个数据。
  • 优点:对于频繁的遍历操作,LinkedHashSet效率高于HashSet
    在这里插入图片描述在这里插入图片描述
    在这里插入图片描述

4、Set接口实现类之三TreeSet

采取红黑树存储结构
在这里插入图片描述
在这里插入图片描述

package com.collection.test.collection;

import org.junit.Test;

import java.util.Comparator;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

/**
 * 1、向TreeSet中添加的数据,要求是相同类的对象
 * 2、两种排序方式:自然排序  和  定制排序
 * 3、自然排序中,比较两个对象是否相同的标准为:compareTo()返回0,不再是equals().
 * 4、定制排序中,比较两个对象是否相同的标准为:compareTo()返回0,不再是equals().
 *
 * DATE: 2022/4/17 16:38
 */
public class TreeSet01 {
    
    
//    1、自然排序:在Person实体类中重写compareTo方法
    @Test
    public void test01(){
    
    
        Set set = new TreeSet();
        set.add(new Person("Tom","18"));
        set.add(new Person("Jack","16"));
        set.add(new Person("Marry","19"));
        set.add(new Person("Rose","20"));
        set.add(new Person("Mike","12"));
        set.add(new Person("Mike","23"));
        Iterator iterator = set.iterator();
        while(iterator.hasNext()){
    
    
            System.out.println(iterator.next());
        }
    }

//    2、定制排序
    @Test
    public void test02(){
    
    
        Comparator com = new Comparator() {
    
    
            @Override
            public int compare(Object o1, Object o2) {
    
    
                if(o1 instanceof Person && o2 instanceof Person){
    
    
                    Person person1 = (Person) o1;
                    Person person2 = (Person) o2;
                    return person1.getAge().compareTo(person2.getAge());
                }else {
    
    
                    throw new RuntimeException("输入的类型不匹配");
                }
            }
        };
        Set set = new TreeSet(com);
        set.add(new Person("Tom","18"));
        set.add(new Person("Jack","16"));
        set.add(new Person("Marry","19"));
        set.add(new Person("Rose","20"));
        set.add(new Person("Mike","12"));
        Iterator iterator = set.iterator();
        while(iterator.hasNext()){
    
    
            System.out.println(iterator.next());
        }
    }


}

Person类

  //按照姓名从a到z排序
    @Override
    public int compareTo(Object o) {
    
    
        if(o instanceof Person){
    
    
            Person person = (Person) o;
            int compare =  this.name.compareTo(person.name);
            if(compare != 0){
    
    
                return compare;
            }else{
    
    
                return this.age.compareTo(person.age);
            }
        }else{
    
    
            throw new RuntimeException("输入的餐厨类型有误");
        }
    }
    //按照姓名从z到a排序
//    @Override
//    public int compareTo(Object o) {
    
    
//        if(o instanceof Person){
    
    
//            Person person = (Person) o;
//            return -this.name.compareTo(person.name);
//        }else{
    
    
//            throw new RuntimeException("输入的餐厨类型有误");
//        }
//    }

猜你喜欢

转载自blog.csdn.net/qq_46112274/article/details/124229483
今日推荐