天天看点

Set

什么是set

Set 具有与 Collection 完全一样的接口 行为上不同 Set 不保存重复的元素

分类

  1. HashSet:最主要的实现类 线程不安全 可以存储null
  2. LinkedHashSet:作为HashSet子类 遍历内部数据时 可以按照添加的方式来显示
  3. TreeSet:可以按照添加对象的指定属性 进行排序

Set特点

  • 无序:存储的数据在底层中并非按照数据的索引 而是根据数据的哈希值来确定位置
  • 不可重复:保证添加的元素按照equals判断时 不能返回true 即相同的元素只能添加一个
  • Set接口中没有拓展Collection中的方法(
  • 向Set接口中添加数据时 其所在的类一定要重写 hashCode() 和 equals()方法 相等的对象必须拥有相等的散列码

HashSet添加元素过程

向HashSet添加 元素 a 首先调用a所在类的hashCode()方法 计算a的哈希值
此哈希值通过HashSet内部某种算法计算出 a  在HashSet中的位置(即为 索引位置)
判断此位置上是否有值
		如果没有 元素 a 添加成功   ==>情况1
		如果存在元素 b(或者以链表存在的多个元素) 则比较元素 a 和 元素 b 的hash值
				如果不相同 添加成功	==>情况2
				如果相同 调用元素 a 所在类的equals方法
						equals返回true 添加失败
						equals返回false 添加成功	=>情况3
情况2和情况3 元素 a 和 已经存在指定索引位置的元素以链表的方式进行存储
jdk8:原来的数据在数组中 指向元素 a
jdk7:a放到数组中 指向原来的数据

HashSet底层:  数组 + 链表
           

示例

HashSet

package com.collection;


import org.junit.Test;

import java.util.HashSet;
import java.util.Set;

/*
* Set接口
* 无序 不可重复
* 无序:存储的数据在底层中并非按照数据的索引 而是根据数据的哈希值来确定位置
* 不可重复:保证添加的元素按照equals判断时 不能返回true  即相同的元素只能添加一个
* Set接口中没有拓展Collection中的方法
* */
public class Demo03 {

    @Test
    public void test(){
        Set set = new HashSet();
        set.add(111);
        set.add(222);
        set.add(333);
        set.add(111);
        set.add(new User("yyll",20));
        set.add(new User("yyll",20));
        System.out.println(set);
        /*
        * 输出结果 [333, 222, 111]
        * 不可重复
        * */
    }
}
           

TreeSet

package com.collection;

import org.junit.Test;

import java.util.TreeSet;

public class Demo04 {

    @Test
    public void test(){
        TreeSet treeSet = new TreeSet();
        treeSet.add(123);
        treeSet.add(445);
        treeSet.add(1323);
        treeSet.add("bb");
        /*
        * java.lang.Integer cannot be cast to java.lang.String
        *
        * 不能添加不同类型的数据
        * TreeSet
        * */
    }
}
           

小结

  1. Set接口

    无序

    不可重复

  2. TreeSet

    不能添加不同类型的数据 可以自定义排序规则

即使再小的帆也能远航