集合中的set(三)

目录

一、框架

二、set中自己定义的方法

三、set:存储无序的、不可重复的数据以HashSet为例说明:

四、添加元素的过程:以Hashset为例:(底层逻辑)

五、LinkedHashSet的使用

六、TreeSet的使用 


 

一、框架

/----Collection接口:单列集合,用来存储的一个一个的对象
      /----Set接口:存储的无序的,不可重复的数据(类似于高中的集合)
          /----HashSet : 作为set接口的主要实现类,线程不安全的,可以存储null值
          /----LinkedHashSet:作为HashSet的子类,遍历其内部数据时,可以按照添加的顺序遍历
              优点:对于频繁的遍历操作,LinkedHashSet效率高于Hashset
          /----TreeSet:可以按照添加对象的指定属性,进行排序。

二、set中自己定义的方法

 1. Set接口中没有额外定义新的方法,使用的都是collection中声明过的方法。
 2.要求:向Set中添加的数据,其所在的类一定要重写hashcode( )和equals()
    要求:重写的hashCode()和equals()尽可能保持一致性:相等的对象必须具有相等的散列码,一般直接调就好了

三、set:存储无序的、不可重复的数据以HashSet为例说明:

1.无序性:不等于随机性。存储的数据在底层数组中并非按照数组索引的顺序添加,而是根据数据的哈希值来排序的。
2.不可重复性:保证添加的元素按照equals()判断时,不能返回true。即:相同的元素只能添加一个。

四、添加元素的过程:以Hashset为例:(底层逻辑)

我们向HashSet中添加元素a,首先调用元素a所在类的hashCode()方法,计算元素a的哈希值,
此哈希值接着通过某种算法计算出在HashSet底层数组中的存放位置(即为:索引位置),判断数组此位置上是否已经有元素:
      如果此位置上没有其他元素,则元素α添加成功。--->情况1
      如果此位置上有其他元素b(或以链表形式存在的多个元素),则比较元素a与元素b的hash值:
          如果hash值不相同,则元素α添加成功。--->情况2
          如果hash值相同,进而需要调用元素α所在类的equals()方法:
              equals()返回true,元素α添加失败
              equals()返回faLse,则元素α添加成功。--->情况3

 对于添加成功的情况2和情况3而言:元素α与已经存在指定索引位置上数据以链表的方式存储。
 jdk 7 ∶元素a放到数组中,指向原来的元素。
 jdk 8 ∶原来的元素在数组中,指向元素d

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

五、LinkedHashSet的使用

    LinkedHashSet作为HashSet的子类,在添加数据的同时,每个数据还维护了两个索引,记录此数据的前一个数据和后一个数据
    优点:对于频繁的遍历操作,LinkedHashSet效率高于Hashset

六、TreeSet的使用 

1.向Treeset中添加的数据,要求是相同类的对象。
2.两种排序方式:自然排序( 实现Comparable接口)和定制排序(实现Comparator)
3.自然排序中,比较两个对象是否相同的标准为: compareTo()返回值,如果是0,那就判断两个对象相同。而不用equals().
4.定制排序中,比较两个对象是否相同的标准为: compare()返回值,如果是0,那就判断两个对象相同。而不用equals().

定制排序代码展示:

    @Test
    public void test2() {
        Comparator comparator = new Comparator() {
            @Override
//            按照年龄从小到大排序
            public int compare(Object o, Object t1) {
                if (o instanceof Person && t1 instanceof Person) {
                    Person p1 = (Person) o;
                    Person p2 = (Person) t1;
                    return Integer.compare(p1.getAge(), p2.getAge());
                } else {
                    throw new RuntimeException("数据类型不匹配");
                }
            }
        };

        TreeSet treeSet = new TreeSet(comparator);//这里有带参数的构造器

        treeSet.add(new Person(12, "q"));
        treeSet.add(new Person(5, "a"));
        treeSet.add(new Person(88, "l"));
        treeSet.add(new Person(43, "b"));
        treeSet.add(new Person(2, "d"));
        treeSet.add(new Person(9, "d"));

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

java塑造中...

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值