ht-6 hashSet特性

Set接口:

 Set接口是Collection接口的另外一个常用子接口,Set接口描述的是一种比较简单的集合,集合中的对象并不按特定的方式排序,并且不能保存重复的对象,即set接口可以存储一组唯一的无序的对象。

为什么要用HahSet?
    假如我们现在想要在一大堆数据中查找X数据。LinkedList的数据结构就不说了,它的数据结构决定了它的查找效率低的可怕。如果使用ArrayList,在不知道数据的索引,且需要全部遍历的情况下,效率一样的低下。为此,Java集合提供了一个查找效率高的集合类HashSet,该类实现了Set接口,是使用Set集合是最常用的一个实现类,HashSet特性如下:

(1)集合内的元素是无序排列的

(2)HashSet类是非线程安全的

(3)允许集合元素值为null

HashSet类常用方法:

boolean add(Object o) 如果此set集合中尚未傲寒指定元素o,则添加指定元素o

void clear()   从Set集合中移除所有元素

int size()  返回set集合中元素的数量

boolean is Empty()   如果此Set不包含任何元素,则返回true

boolean contains(Object o)  如果此Set包含指定元素,则返回true

boolean remove(Object o)  如果指定元素存在于此Set中,则将其移除

简单示例:

 1 package com.iotek.set;
 2 
 3 import java.util.HashSet;
 4 
 5 public class HashSetDemo1 {
 6 
 7     public static void main(String[] args) {
 8         HashSet<String> data = new HashSet<String>();
 9         // 创建一个HashSet容器对象
10         data.add("zhangsan");
11         data.add("lisi");
12         System.out.println("1:" + data.add("jay")); // 如果添加成功, add()方法返回true
13         data.add("jack");
14         System.out.println("2:" + data.add("jay"));
15         System.out.println(data);
16         HashSet<Student> stuSet = new HashSet<Student>();
17         // 把Student对象作为HashSet底层的HashMap里边的键
18         System.out.println("3:" + stuSet.add(new Student("zhangsan", 20)));
19         System.out.println("4:" + stuSet.add(new Student("lisi", 20)));
20         System.out.println("5:" + stuSet.add(new Student("zhangsan", 20)));
21         // 没有重写hashCode()和equals()前,这个重复的对象可以添加进去,重写了之后,就无法添加
22         System.out.println("6:" + stuSet.size());
23     }
24 
25 }
26 
27 class Student {
28     private String name;
29     private int age;
30 
31     public Student(String name, int age) {
32         super();
33         this.name = name;
34         this.age = age;
35     }
36 
37     public String getName() {
38         return name;
39     }
40 
41     public void setName(String name) {
42         this.name = name;
43     }
44 
45     public int getAge() {
46         return age;
47     }
48 
49     public void setAge(int age) {
50         this.age = age;
51     }
52 
53     // 只有当2个对象的hashCode和equals()返回值都相同,才能认定为是同一个对象
54     @Override
55     public int hashCode() {
56         final int prime = 31;
57         int result = 1;
58         result = prime * result + age;
59         result = prime * result + ((name == null) ? 0 : name.hashCode());
60         return result;
61     }
62 
63     @Override
64     public boolean equals(Object obj) {
65         if (this == obj)
66             return true;
67         if (obj == null)
68             return false;
69         if (getClass() != obj.getClass())
70             return false;
71         Student other = (Student) obj;
72         if (age != other.age)
73             return false;
74         if (name == null) {
75             if (other.name != null)
76                 return false;
77         } else if (!name.equals(other.name))
78             return false;
79         return true;
80     }
81 
82 }
83 /*
84  * HashSet原理分析: (1)当调用HashSet的无参构造方法创建一个HashSet对象时, 其内部自动创建了一个HashMap对象,如下所示:
85  * public HashSet() { map = new HashMap<E,Object>(); }
86  * 
87  * (2)HashSet没有put()方法,只有add()方法,原因是,这个add()方法其实调用的
88  * 是HashSet()构造方法创建的map对象的put()方法来对数据进行存储,其实操作的是 HashMap对象里的键,值是定义的一个静态常量PRESENT
89  * public boolean add(E e) { return map.put(e, PRESENT)==null; }
90  * (3)size()方法:其实就是返回map对象里的size()方法返回的数据个数 public int size() { return
91  * map.size(); }
92  */

结果如下

HashSet本质:

 HashSet底层维护了一个hashMap, set中添加的元素,被作为这个HashMap的key, hashmap键是不能重复的,所以HashSet内部的元素也是不能重复的 ,对于HashSet中保存的对象,需要正确重写equals方法和hashCode方法,以保证放入Set对象的唯一性,正因为这样的原理,HashSet集合是非常高效的,比如,要查找集合中是否包含某个对象,首先计算对象的hashCode,折算出位置号,到该位置上去找就可以了,而不用和所有的元素都比较一遍

 参考文章:

https://blog.csdn.net/sugar_rainbow/article/details/68257208 

https://www.cnblogs.com/whgk/p/6114842.html

 

posted @ 2018-07-30 22:50  清风拂来  阅读(221)  评论(0编辑  收藏  举报