栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Set接口

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Set接口

目录

一、概述

二、Set的无序性与不可重复性的理解

1.无序性(≠随机性) 

2.不可重复性

三、添加元素的过程(以HashSet为例)

我们向HashSet中添加元素a:

⚪说明:

HashSet的底层:数组 + 链表的结构 

四、Set的实现类:

1、Set实现类之一:HashSet

①HashSet具有以下特点:

②HashSet集合判断两个元素相等的标准:

③“相等的对象必须具有相等的散列码”

2、Set实现类之二:linkedHashSet

3、Set实现类之三:TreeSet

五、重写hashCode()方法的基本原则


一、概述

Set接口中没有额外定义新的方法,使用的都是Collection中声明的方法

二、Set的无序性与不可重复性的理解

1.无序性(≠随机性) 

存储的数据在底层数组中并非按照数组索引的顺序添加,而是根据数据的哈希值决定的

2.不可重复性

保证添加的元素按照equals()判断时,不能返回true即,相同的元素只能添加一个

public class SetTest {
    @Test
    public void test1(){
        Set set = new HashSet();
        set.add(456);
        set.add(123);
        set.add(123);
        set.add("AA");
        set.add("CC");
        set.add(new User("Tom",12));
        set.add(new User("Tom",12));
        set.add(129);

        Iterator iterator = set.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }
}

public class User {
    private String name;
    private int age;

    public User(String name, int age) {
        this.name = name;
        this.age = 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;
    }

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

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

        User user = (User) o;

        if (age != user.age) return false;
        return name != null ? name.equals(user.name) : user.name == null;
    }

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

三、添加元素的过程(以HashSet为例)

我们向HashSet中添加元素a:

    调用元素a所在类的hashCode()方法,计算a的哈希值

    此哈希值通过某种计算方法计算出在HashSet底层数组中存放的位置(即为相应的索引位置)

    判断数组此位置上是否已有元素,如果没有,则元素a添加成功,如果此位置上有其他元素b,或以链表形式存在的多个元素,则比较元素a与元素b的哈希值,如果哈希值不相同,则元素a添加成功;如果哈希值相同,进而需要调用元素a所在类的equals()方法

    equals()返回true,元素a添加失败;若返回false,则元素a添加成功

⚪说明:

对于后两种添加成功的情况而言,元素a与已经存在指定索引位置上数据以链表的方式存储

jdk7中:元素a放到数组中

jdk8中:原来的元素中,指向元素a

即:七上八下

HashSet的底层:数组 + 链表的结构 

四、Set的实现类:

1、Set实现类之一:HashSet

是Set接口的主要实现类,是线程不安全的,可以存储null值

①HashSet具有以下特点:
    不能保证元素的排列顺序HashSet不是线程安全的集合元素可以是null

②HashSet集合判断两个元素相等的标准:

两个对象通过hashCode()方法比较相等,并且两个对象的equals()方法返回值也相等

③“相等的对象必须具有相等的散列码”

对于存放在Set容器中的对象,对应的类一定要重写equals()和hashCode(Object obj)方法,以实现对象相等的规则

2、Set实现类之二:linkedHashSet

作为HashSet的子类出现;遍历其内部数据时,可以按照添加的顺序遍历

对于频繁的遍历操作,linkedHashSet效率高于HashSet

    @Test
    public void test1(){
        Set set = new linkedHashSet();
        set.add(456);
        set.add(123);
        set.add(123);
        set.add("AA");
        set.add("CC");
        set.add(new User("Tom",12));
        set.add(new User("Tom",12));
        set.add(129);

        Iterator iterator = set.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }

3、Set实现类之三:TreeSet

底层用红黑树存储,可以按照添加对象的指定属性进行排序

    向TreeSet中添加的数据,要求是相同类的对象,不能添加不同类的对象两种排序方式:自然排序(实现Comparable接口)和定制排序(Comparator) 自然排序中,比较两个对象是否相同的标准为:compareTo()返回0,不再是equals() 此时,第二个Jack并没有显示出来,需要我们进行二级排序定制排序中,比较两个对象是否相同的标准为:compare()返回0,不再是equals()
    @Test
    public void test2(){
        Comparator com = new Comparator() {
            //按照年龄从小到大排列
            @Override
            public int compare(Object o1, Object o2) {
                if(o1 instanceof User && o2 instanceof User){
                    User u1 = (User) o1;
                    User u2 = (User) o2;
                    return Integer.compare(u1.getAge(),u2.getAge());
                }else{
                    throw new RuntimeException("输入的数据类型不匹配");
                }
            }
        };
        TreeSet set = new TreeSet(com);
        set.add(new User("Tom",12));
        set.add(new User("Jerry",32));
        set.add(new User("Jim",2));
        set.add(new User("Mike",65));
        set.add(new User("Jack",33));
        set.add(new User("Marry",33));
        set.add(new User("Jack",56));

        Iterator iterator = set.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }

五、重写hashCode()方法的基本原则

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/704644.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号