首页 > 其他 > 详细

集合:set接口及其实现类(HashSet、TreeSet底层结构)

时间:2020-08-06 18:30:36      阅读:92      评论:0      收藏:0      [点我收藏+]

1、set接口

(1)特点

  • 元素不能重复(equals判断)
  • 无序
    @Test
    public void test1() {
        Set set=new HashSet();
        set.add("zhai");
        set.add("123");
        set.add("null");
        set.add("123");
        set.add("90");
        System.out.println(set);
    }
D:\IdeaProjects\test_03\src\com\zhb\test\DateDemo.java

注意:Treeset不允许添加null元素

(2)特有方法

没有特有方法,主要是重collection接口继承来的

(3)遍历方式

和collection接口的遍历方式相同:迭代器、增强for

 

2、HashSet底层结构

(1)底层结构

  • 哈希表
public HashSet() {
        map = new HashMap<>();
    }

因为HashSet维护的是一个HashMap对象,而HashMap维护的是一个哈希表,两者都是基于hash结构的

  • 无序:根据哈希值确定元素在哈希表中的位置

(2)去除重复原理

技术分享图片

 

 原理:

先获取元素的哈希值,通过一些运算获取一个整数索引index(要存放在数组的位置)

如果索引处没有元素,则直接添加

如果索引处有其他元素,则需要进行equals判断,如果不相等,则以链表的形式追加到已有元素的后面并返回true,如果相等则直接覆盖并返回false

如果不是哈希表的结构,需要进行大量的equals判断,哈希表的使用大大减少了equals的使用

 

重写equals与hashCode方法(https://www.cnblogs.com/zhai1997/p/11354885.html

存储已经存在的数据类型的数据,不用重写equals和hashcode方法,即可去除重复元素

存储自定义类型的数据需要重写equals和hashcode方法

 

3、TreeSet底层结构

(1)底层结构

基于map对象(TreeMap),treeMap的底层是红黑树的结构,可以实现对元素的排序

(2)特点

  • 不允许重复
  • 可以实现对里面的元素进行排序(自然排序、定制排序)

技术分享图片

 

  •  红黑树存储的时候是左边的存较小的元素,右边存储较大的元素,取出的时候可以按顺序取出,先取出20,然后25... ...
  • 红黑树与二叉树的不同是,红黑树给二叉树标记了颜色,例如:左边红色右边黑色,当左边的红色元素过多右边黑色元素过少的时候,红黑树就失去了平衡,此时就要重新打乱顺序重新选出根元素,使得两边保持平衡
  • 红黑树是二叉树的一种

(3)TreeSet的使用

 @Test
    public void test1() {
        Set set=new TreeSet();
        set.add(new Student("zhai",12));
        set.add(new Student("zz",13));
        set.add(new Student("zhang",14));
        set.add(new Student("liu",19));
        set.add(new Student("zhang",14));
        for (Object s: set){
            System.out.println(s);
        }
    }
java.lang.ClassCastException: com.zhb.domain.Student cannot be cast to java.lang.Comparable

报错的类型是类型转换异常,原因是添加元素的时候在确定元素在二叉树中的位置的时候,需要当前元素与结点元素进行比较,小的左,大的右,相等的话不添加,但是对象不具有比较性,因此报错

要让其具有比较性有两种方法:

自然排序:

public class Student implements Comparable{
    public String sname;
    public int age;

    @Override
    public String toString() {
        return "Student{" +
                "sname=‘" + sname + \‘ +
                ", age=" + age +
                };
    }

    public Student(String sname, int age) {
        this.sname = sname;
        this.age = age;
    }

    public String getSname() {
        return sname;
    }

    public void setSname(String sname) {
        this.sname = sname;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }


    @Override
    public int compareTo(Object o) {
        Student s=(Student)o;
        return Integer.compare(this.age,s.age);
    }
}
Student{sname=zhai, age=12}
Student{sname=zz, age=13}
Student{sname=zhang, age=14}
Student{sname=liu, age=19}

此方法需要实现接口重写方法

定制排序:

 @Test
    public void test1() {
        Set set=new TreeSet(new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                Student s1=(Student)o1;
                Student s2=(Student)o2;
                return Integer.compare(s1.getAge(),s2.getAge());
            }
        });
        set.add(new Student("zhai",12));
        set.add(new Student("zz",13));
        set.add(new Student("zhang",14));
        set.add(new Student("liu",19));
        set.add(new Student("zhang",14));
        for (Object s: set){
            System.out.println(s);
        }
    }
Student{sname=zhai, age=12}
Student{sname=zz, age=13}
Student{sname=zhang, age=14}
Student{sname=liu, age=19}

在定义TreeSet的同时定义比较器

(4)添加方法原理

底层是treemap的添加:

技术分享图片

 

 进行元素的比较:

技术分享图片

 

 调用的比较器:

技术分享图片

 

(5)如何实现去重

通过比较方法(compareTo方法)的返回值是否为0来判断元素是否重复

 

集合:set接口及其实现类(HashSet、TreeSet底层结构)

原文:https://www.cnblogs.com/zhai1997/p/13447118.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!