zoukankan      html  css  js  c++  java
  • 集合(3)—— Set

    一、什么是Set?

    Set接口是Collection接口的子接口,是一种不允许重复元素的集合。

     

    二、HashSet

    • HashSet是Set的一个典型实现类,无序,不可重复,允许加入NULL,大多数时候使用Set就是使用这个类,HashSet按照Hash算法来存储元素,因此具备很好的存取和查找性能。
    • 其底层其实是一个数组,存在的意义是加快查询速度,我们知道一般的数组,元素在其中的索引位置都是随机的,元素的取值和位置之间没有关联关系,因此,在数组中查找特定的元素时,只能逐个比较,查找速度取决于比较的次数。但是在HashSet底层的数组中,索引和值之间存在确定的关系:index=hash(value),因此通过这个关系可以快速的找到元素或者索引。
    • 当在HashSet中存储元素时,首先调用该对象的hashCode()方法,获取hashCode值,根据这个值,找到对应位置,HashSet中不允许重复,判断方法是:先比较hashCode是否相同,不同就认为是不同对象,相同的话再比较equals方法,根据结果判断。
    • 每一个存储到哈希表中的对象,都要提供equals方法和hashCode方法实现,以判断是否是相同对象,对于HashSet,我们应该保证如果两个对象通过equals方法返回true,hashCode值也相同。

    三、LinkedHashSet

    LinkedHashSet是有序,不允许重复,允许加入NULL的集合。

    它也是以HashCode值来决定元素的存储位置,同时还使用了链表来维护元素的顺序,这就使得它按照插入的顺序有序排列。相比Hashset多维护了链表,因此性能略低于HashSet。

    四、TreeSet

    TreeSet是有序,不允许重复,不允许NULL的集合。底层使用红黑树算法,擅长范围查询。

    • 如果使用TreeSet的无参构造器新建一个TreeSet对象,要求存储其中的元素实现Comparable接口,所以在其中不能存入NULL
    • 必须存入相同类型的对象(默认会进行排序),否则会出现类型转换异常!一般使用泛型来进行限制。
    • 自然排序:要求被添加的参数对象必须实现Comparable接口,并且覆盖了compareTo(Object obj)方法:

      如果 this>obj ,返回1,

      如果 this=obj ,返回0,

      如果 this<obj ,返回-1。

      通过该方法定义的规则比较之后,按照升序排列。

    • 定制排序:创建TreeSet对象时,传入实现了Compartor接口的实现类,通过compare方法定义的规则进行定制排序(如倒序),要求该实现类的compare方法和equals方法具有一致性,即:compare方法中,两个对象相等时应该return 0。

    如下,按照money多少降序排列:

     1 package com.vi.collection.set;
     2 
     3 import java.util.Comparator;
     4 import java.util.TreeSet;
     5 
     6 public class TreeSetDemo {
     7     public static void main(String[] args) {
     8         Man m1 = new Man(1000);
     9         Man m2 = new Man(2000);
    10         Man m3 = new Man(3000);
    11         Man m4 = new Man(2500);
    12         TreeSet<Man> ts = new TreeSet<>(new Man(0));
    13         ts.add(m1);
    14         ts.add(m2);
    15         ts.add(m3);
    16         ts.add(m4);
    17         System.out.println(ts);
    18     }
    19 }
    20 
    21 class Man implements Comparator<Man> {
    22     double money;
    23 
    24     public int compare(Man m1, Man m2) {
    25         if (m2.money > m1.money)
    26             return 1;
    27         if (m2.money == m1.money)
    28             return 0;
    29         return -1;
    30     }
    31 
    32     public Man(double money) {
    33         this.money = money;
    34     }
    35 
    36     public String toString(){
    37         return money+" ";
    38     }
    39 
    40 }
    View Code

     五、对以上三种Set进行比较

    共同点:

    1.都不允许存入重复值

    2.都是线程不安全的(解决办法:使用Collections.synchronizedSet()方法)

    不同点:

    1.TreeSet不允许NULL值,HashSet和LinkedList可以存入空值

    2.HashSet是无序的底层采用哈希表算法,查询效率高,通过equals()和hashCode()共同判断对象是否相等,即要求存入的对象重写equals()和hashCode()保持一致性;

    LinkedList底层采用了哈希表和链表的结构,既保证了元素的添加顺序,也保证了查询效率,性能略低于HashSet;

    TreeSet不保证元素的添加顺序,但是会按照自然排序或定制规则对集合中元素进行排序,底层采用了红黑树算法(树结构比较适合范围查询)。

  • 相关阅读:
    700. Search in a Binary Search Tree
    100. Same Tree
    543. Diameter of Binary Tree
    257. Binary Tree Paths
    572. Subtree of Another Tree
    226. Invert Binary Tree
    104. Maximum Depth of Binary Tree
    1、解决sublime打开文档,出现中文乱码问题
    移植seetafaceengine-master、opencv到ARM板
    ubuntu16.04-交叉编译-SeetaFaceEngine-master
  • 原文地址:https://www.cnblogs.com/blogforvi/p/11626793.html
Copyright © 2011-2022 走看看