Java集合之Set

Set继承于Collection接口,是一个不允许出现重复元素且无序的集合,有hashset和treeSetl两大实现类

在判断重复元素的时候,Set集合会调用hashCode()和equals()方法来实现

HashSet是哈希表结构,主要利用HashMap的key来存储元素,计算插入元素的hashCode来获取元素在集合中的位置;

TreeSet是红黑数结构,每一个元素都是树中的一个节点,插入的元素都会进行排序;

Set集合框架结构:

set集合添加元素并使用迭代器迭代元素。

public class Demo4 {
    public static void main(String[] args) {
        //Set 集合存和取的顺序不一致。
        Set hs = new HashSet();
        hs.add("世界军事");
        hs.add("兵器知识");
        hs.add("舰船知识");
        hs.add("汉和防务");
        System.out.println(hs);
        // [舰船知识, 世界军事, 兵器知识, 汉和防务]
        Iterator it = hs.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }
    }
}

Set还提供了equals(Object o)和hashCode(),供其子类重写,以实现对集合中插入重复元素的处理;

public interface Set<E> extends Collection<E> {

    A:添加功能
    boolean add(E e);
    boolean addAll(Collection<? extends E> c);

    B:删除功能
    boolean remove(Object o);
    boolean removeAll(Collection<?> c);
    void clear();

    C:长度功能
    int size();

    D:判断功能
    boolean isEmpty();
    boolean contains(Object o);
    boolean containsAll(Collection<?> c);
    boolean retainAll(Collection<?> c); 

    E:获取Set集合的迭代器:
    Iterator<E> iterator();

    F:把集合转换成数组
    Object[] toArray();
    <T> T[] toArray(T[] a);
    
    //判断元素是否重复,为子类提高重写方法
    boolean equals(Object o);
    int hashCode();
}

HashSet

接口 实现该接口可以使用增强for循环
                ---| Collection        描述所有集合共性的接口
                    ---| List接口        可以有重复元素的集合
                            ---| ArrayList   
                            ---|  LinkedList
                    ---| Set接口        不可以有重复元素的集合
                            ---| HashSet  线程不安全,存取速度快。底层是以哈希表实现的。

 

(1)HashSet继承AbstractSet类,获得了Set接口大部分的实现,减少了实现此接口所需的工作,实际上是又继承了AbstractCollection类;

(2)HashSet实现了Set接口,获取Set接口的方法,可以自定义具体实现,也可以继承AbstractSet类中的实现;

(3)HashSet实现Cloneable,得到了clone()方法,可以实现克隆功能;

(4)HashSet实现Serializable,表示可以被序列化,通过序列化去传输,典型的应用就是hessian协议。

具有如下特点:

  • 不允许出现重复因素;

  • 允许插入Null值;

  • 元素无序(添加顺序和遍历顺序不一致);

  • 线程不安全,若2个线程同时操作HashSet,必须通过代码实现同步;

  • HashSet  --> 是由HashMap维护的
            无序的,不可重复

            底层结构: 哈希表(数组+链表+红黑树)
            特点: 查询,增删效率较高
                  无序,去重
            应用场景 : 存储数据由单个值决定的情况下,想要去重的情况下,适合使用HashSet
            新增内容 : 无新增方法

  • HashSet
    1. 由Hashmap维护的,无序的,不可重复的
    2. 底层结构:哈希表(数组+链表+红黑树)
    3. 特点:查询,增删效率较高,无序,可去重
    4. 应用场景:存储数据由单个值决定的情况下,想要去重的情况下,适合使用hashset
    5. 哈希表中hashcode与equals之间的关系(前提是重写hashcode与equals都是根据成员变量计算)equals相等hashcode一定相等,hashcode相等,equals不一定相等
    6. 哈希表存储自定义引用数据的去重:需要在数据的类型中重写equals与hashcode方法

实现根据内容(成员变量的值)进行比较和计算

元素的哈希值是通过元素的hashcode方法 来获取的, HashSet首先判断两个元素的哈希值,如果哈希值一样,接着会比较equals方法 如果 equls结果为true ,HashSet就视为同一个元素。如果equals 为false就不是同一个元素。

哈希值相同equals为false的元素是怎么存储呢,就是在同样的哈希值下顺延(可以认为哈希值相同的元素放在一个哈希桶中)。也就是哈希一样的存一列。


       TreeSet

--> 是由TreeMap维护的
        无序,去重
        底层结构 : 红黑树(平衡二叉树)
        特点 : 默认升序排序
        新增方法 : 数据的大小比较相关的方法,因为红黑树结构中数据已经比较过大小,默认升序

        思考: TreeSet集合中能够成功存储不同类型的数据?
             使用TreeSet存储自定义的引用数据类型,如何是否去重(根据内容去重),实现默认升序排序?

它继承AbstractSet,实现NavigableSet, Cloneable, Serializable接口。

(1)与HashSet同理,TreeSet继承AbstractSet类,获得了Set集合基础实现操作;

(2)TreeSet实现NavigableSet接口,而NavigableSet又扩展了SortedSet接口。这两个接口主要定义了搜索元素的能力,例如给定某个元素,查找该集合中比给定元素大于、小于、等于的元素集合,或者比给定元素大于、小于、等于的元素个数;简单地说,实现NavigableSet接口使得TreeSet具备了元素搜索功能;

(3)TreeSet实现Cloneable接口,意味着它也可以被克隆;

(4)TreeSet实现了Serializable接口,可以被序列化,可以使用hessian协议来传输;

具有如下特点:

接口 实现该接口可以使用增强for循环

---| Collection 描述所有集合共性的接口

---| List接口 有序,可以重复,有角标的集合

---| ArrayList ---| LinkedList ---| Set接口 无序,不可以重复的集合

---| HashSet 线程不安全,存取速度快。底层是以hash表实现的。

---| TreeSet 红-黑树的数据结构,默认对元素进行自然排序(String)。

TreeSet<Double> tree = new TreeSet<>();

        tree.add(3.3);
        tree.add(1.1);
        tree.add(2.2);
        tree.add(4.4);
        tree.add(5.5);
        tree.add(5.5);

        System.out.println(tree);

        //测试新增 方法
        System.out.println(tree.first());
        System.out.println(tree.last());
        System.out.println(tree.ceiling(2.1));
        System.out.println(tree.floor(3.3));

        TreeSet<String> tree2 = new TreeSet<>();

        tree2.add("abc");
        tree2.add("bc");
        tree2.add("ab");
        tree2.add("a");
        tree2.add("b");
        tree2.add("ab");

        System.out.println(tree2);

比较器接口

----| Comparable
               compareTo(Object o)     元素自身具备比较性
----| Comparator
               compare( Object o1, Object o2 )    给容器传入比较器
 

一,让元素自身具备比较性。

也就是元素需要实现Comparable接口,覆盖compareTo 方法。

这种方式也作为元素的自然排序,也可称为默认排序。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值