java-集合-set(不重复集合)知识分解——庖丁解牛版

发布时间:2022-07-02 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了java-集合-set(不重复集合)知识分解——庖丁解牛版脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

目录

庖丁解牛法总纲

第一重境界:所见莫非全牛者

1、概述:

2、Set集合特点:

3、分类(实现子类):

 4、所有已知实现类:

 5、注意事项

 6、所有方法

第二重境界:未尝见全牛也

HashSet

1、HashSet特点:

2、HashSet集合添加一个元素的过程:

3、代码演示

 4、注意事项(特殊之处,遍历无序的原因不是排序的无序,而是底层哈希值的存放地址的原因)

5、LinkedHashSet集合概述和特点

TreeSet

1、TreeSet集合特点

2、注意事项

3、代码展示(比较器排序)

第三重境界:官知止而神欲行

1、哈希值(hashCode)

概念:

特点:

代码展示:

2、哈希表

概念:

哈希表的实现:

哈希表的优缺点:

哈希表的学习:


庖丁解牛术法总纲

       吾生也有涯,而知也无涯 。以有涯随无涯,殆已!已而为知者,殆而已矣!为善无近名,为恶无近刑。缘督以为经,可以保身,可以全生,可以养亲,可以尽年。

       “庖丁为文惠君解牛,手之所触,肩之所倚,足之所履,膝之所踦,砉然向然,奏刀騞然,莫不中音。合于《桑林》之舞,乃中《经首》之会。

       文惠君曰:“嘻,善哉!技盖至此乎?”

       庖丁释刀对曰:“臣之所好者,道也,进乎技矣。始臣之解牛之时,所见无非牛者。三年之后,未尝见全牛也。方今之时,臣以神遇而不以目视,官知止而神欲行。依乎天理,批大郤,导大窾,因其固然,技经肯綮之未尝,而况大軱乎!良庖岁更刀,割也;族庖月更刀,折也。今臣之刀十九年矣,所解数千牛矣,而刀刃若新发于硎。彼节者有间,而刀刃者无厚;以无厚入有间,恢恢乎其于游刃必有余地矣,是以十九年而刀刃若新发于硎。虽然,每至于族,吾见其难为,怵然为戒,视为止,行为迟。动刀甚微,謋然已解,如土委地。提刀而立,为之四顾,为之踌躇满志,善刀而藏之。”

                                                                                                                ——《庄子·养生主》

呔,妖怪。看法宝!

java-集合-set(不重复集合)知识分解——庖丁解牛版

第一重境界:所见莫非全牛者

1、概述:

       Set集合类似于一个罐子,程序可以依次把多个对象“丢进”Set集合,而Set集合通常不能记住元素的添加顺序。实际上Set就是Collection,只是行为略有不同(Set不允许包含重复元素)。        Set集合不允许包含相同的元素,如果试图把两个相同元素加入同一个Set集合中,则添加操作失败,add()方法返回false,且新元素不会被加入。

2、Set集合特点:

(1)、不包含重复元素的集合

(2)、没有带索引的方法,所以不能使用普通for循环遍历

3、分类(实现子类):

(1)、HashSet

(2)、TreeSet

 4、所有已知实现类:

@H_662_126@
  • AbstractSetConcurrentHashMap.KeySetViewConcurrentSkipListSetCopyOnWrITeArraySetEnumSetHashSetJobstateReasonsLinkedHashSetReadOnlySetPRoPErtyReadOnlySetPropertyBaseReadOnlySetWrapperSetBindingSetExPressionSetPropertySetPropertyBaseSimpleSetPropertyTreeSet

  •  5、注意事项

    不包含重复元素的集合。 更正式地,集合不包含一对元素e1e2 ,使得e1.equals(e2) ,并且最多只有一个空元素。 正如其名称所暗示的那样,这个接口模拟了数学抽象。

    Set接口放置额外的约定,超过从继承Collection接口,所有构造函数的合同,而位于该合同addequalshashCode方法。 其他继承方法的声明也包括在这里以方便。 (这些声明中附带的规格已针对Set接口进行了定制,但不包含任何其他规定。)

    构造函数的额外规定并不奇怪,所有构造函数都必须创建一个不包含重复元素的集合(如上所定义)。

    注意:如果可变对象用作设置元素,则必须非常小心。 如果对象的值以影响equals比较的方式更改,而对象是集合中的元素,则不指定集合的行为。 这种禁止的一个特殊情况是,一个集合不允许将其本身作为一个元素。

    一些集合实现对它们可能包含的元素有限制。 例如,一些实现禁止空元素,有些实现对元素的类型有限制。 尝试添加不合格元素会引发未经检查的异常,通常为NullPointerExceptionClassCastException 。 尝试查询不合格元素的存在可能会引发异常,或者可能只是返回false; 一些实现将展现出前者的行为,一些实现将展现出后者。 更一般来说,尝试对不符合条件的元素的操作,其完成不会导致不合格元素插入到集合中,可能会导致异常,或者可能会成功执行该选项。 此异常在此接口的规范中标记为“可选”。

     6、所有方法

      • Modifier and Type方法描述
        booleanadd​(E e)

        如果指定的元素不存在,则将其指定的元素添加(可选操作)。

        booleanaddAll​(Collection<? extends E> c)

        将指定集合中的所有元素添加到此集合(如果尚未存在)(可选操作)。

        voidclear​()

        从此集合中删除所有元素(可选操作)。

        booleancontains​(Object o)

        如果此集合包含指定的元素,则返回 true

        booleancontainsAll​(Collection<?> c)

        如果此集合包含指定集合的所有元素,则返回 true

        booleanequals​(Object o)

        将指定的对象与此集合进行比较以实现相等。

        inthashCode​()

        返回此集合的哈希码值。

        booleaniSEMpty​()

        如果此集合不包含元素,则返回 true

        Iterator<E>iterator​()

        返回此集合中元素的迭代器。

        static <E> Set<E>of​()

        返回一个包含零个元素的不可变集合。

        static <E> Set<E>of​(E e1)

        返回一个包含一个元素的不可变集合。

        static <E> Set<E>of​(E... elements)

        返回一个包含任意数量元素的不可变集合。

        static <E> Set<E>of​(E e1, E e2)

        返回一个包含两个元素的不可变集合。

        static <E> Set<E>of​(E e1, E e2, E e3)

        返回一个包含三个元素的不可变集合。

        static <E> Set<E>of​(E e1, E e2, E e3, E e4)

        返回一个包含四个元素的不可变集合。

        static <E> Set<E>of​(E e1, E e2, E e3, E e4, E e5)

        返回一个包含五个元素的不可变集合。

        static <E> Set<E>of​(E e1, E e2, E e3, E e4, E e5, E e6)

        返回一个包含六个元素的不可变集合。

        static <E> Set<E>of​(E e1, E e2, E e3, E e4, E e5, E e6, E e7)

        返回一个包含七个元素的不可变集合。

        static <E> Set<E>of​(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8)

        返回一个包含八个元素的不可变集合。

        static <E> Set<E>of​(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9)

        返回一个包含九个元素的不可变集合。

        static <E> Set<E>of​(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10)

        返回一个包含十个元素的不可变集合。

        booleanremove​(Object o)

        如果存在,则从该集合中删除指定的元素(可选操作)。

        booleanremoveAll​(Collection<?> c)

        从此集合中删除指定集合中包含的所有元素(可选操作)。

        booleanretainAll​(Collection<?> c)

        仅保留该集合中包含在指定集合中的元素(可选操作)。

        intsize​()

        返回此集合中的元素数(其基数)。

        default Spliterator<E>spliterator​()

        在此集合中的元素上创建一个 Spliterator

        Object[]toArray​()

        返回一个包含此集合中所有元素的数组。

        <T> T[]toArray​(T[] a)

        返回一个包含此集合中所有元素的数组; 返回的数组的运行时类型是指定数组的运行时类型。

    第二重境界:未尝见全牛也

    HashSet

    1、HashSet特点:

    (1)底层数据结构是哈希表(查询速度快),使用HashCode哈希值

    (2)对集合的迭代顺序不作任何保证,也就是说不保证存储和取出的元素顺序一致

    (3)没有带索引的方法,所以不能使用普通for循环遍历

    (4)由于是Set集合,所以是不包含重复元素的集合

    2、HashSet集合添加一个元素的过程:

    java-集合-set(不重复集合)知识分解——庖丁解牛版

          

    3、代码演示

    package SetDemo;
    
    import java.util.HashSet;
    
    public class Set01 {
        public static void main(String[] args) {
            //导包创建对象HashSet
            HashSet<String> set=new HashSet<String>();
    
            //添加数据
            set.add("aaa");
            set.add("bbb");
            set.add("ccc");
            set.add("ddd");
    
            //增强for循环遍历
            for (String i:set){
                System.out.println(i);
            }
    
        }
    }
    
    //代码输出结果
    E:developJDKbinjava.exe "-javaagent:E:IDEAIntelliJ IDEA CommUnity Edition 
    aaa
    ccc
    bbb
    ddd
    
    Process finished with exit code 0

     4、注意事项(特殊之处,遍历无序的原因不是排序的无序,而是底层哈希值的存放地址的原因)

     public static void main(String[] args) {
            HashSet<String> set=new HashSet<String>();
    
            set.add("hello");
            set.add("world");
            set.add("java");
    
            //集合自带排序方式
            System.out.println(set);
            System.out.println("--------");
            //迭代器方式
            Iterator<String> it = set.iterator();
            while (it.hasNext()){
                String s = it.next();
                System.out.println(s);
            }
            System.out.println("--------");
            //增强for循环
            for (String s:set){
                System.out.println(s);
            }
    
     }
    
    //输出结果
    [world, java, hello]
    --------
    world
    java
    hello
    --------
    world
    java
    hello
    
    Process finished with exit code 0

     上述代码是正常输出的结果,但是以下的代码的输出,请看:

    public static void main(String[] args) {
            HashSet<String> set=new HashSet<String>();
    
            set.add("6");
            set.add("7");
            set.add("8");
            set.add("9");
            set.add("10");
    
            //集合自带排序方式
            System.out.println(set);
            System.out.println("--------");
            //迭代器方式
            Iterator<String> it = set.iterator();
            while (it.hasNext()){
                String s = it.next();
                System.out.println(s);
            }
            System.out.println("--------");
            //增强for循环
            for (String s:set){
                System.out.println(s);
            }
    
        }
    
    //代码输出结果
    [6, 7, 8, 9, 10]
    --------
    6
    7
    8
    9
    10
    --------
    6
    7
    8
    9
    10
    
    Process finished with exit code 0
    public static void main(String[] args) {
            HashSet<String> set=new HashSet<String>();
            set.add("a");
            set.add("b");
            set.add("c");
            set.add("d");
            set.add("e");
    
            //集合自带排序方式
            System.out.println(set);
            System.out.println("--------");
            //迭代器方式
            Iterator<String> it = set.iterator();
            while (it.hasNext()){
                String s = it.next();
                System.out.println(s);
            }
            System.out.println("--------");
            //增强for循环
            for (String s:set){
                System.out.println(s);
            }
    
        }
    
    //代码输出结果
    [a, b, c, d, e]
    --------
    a
    b
    c
    d
    e
    --------
    a
    b
    c
    d
    e
    
    Process finished with exit code 0

    上述两则代码结果,可以看到输出结果都是有序的,而HashSet特点有一,就是不保证迭代顺序。这不就是矛盾的一处地方吗?

    原因:但并不是HashSet的自相矛盾,其原因就是底层实现的特点。哈希表实现,计算哈希值,通过哈希值代替索引的作用,查询存储的值。

    而哈希值的计算,有一套自己的计算规则,当一串字符串计算哈希值时,哈希值的区别也许会很大,但如果是有规律的数字、字符进行计算哈希值时,其哈希值有会时有序的。

    表现出来的结果就是在控制台输出有顺序有规律的单节字符时,输出也是有规律的。

    5、LinkedHashSet集合概述和特点

    (1)集合特点:

    哈希表和链表实现的Set接口,具有可预测的迭代顺序。

    由链表保证元素有序,也就是说元素的存储和取出顺序是一致的。

    由哈希表保证元素唯一,也就是说没有重复的元素。

    (2)代码案例

    java-集合-set(不重复集合)知识分解——庖丁解牛版

    TreeSet

    1、TreeSet集合特点

    (1)元素有序,这里的顺序不是指存储和取出的顺序,而是按照一定的规则进行排序,具体排序方式取决于构造方法     TreeSet​():根据其元素的自然排序进行排序     TreeSet​(Comparator<? super E> comparator) :根据指定的比较器进行排序

    (2)没有带索引的方法,所以不能使用普通for循环遍历

    (3)由于是Set集合,所以不包含重复元素的集合

    2、注意事项

    用TreeSet集合存储自定义对象,无参构造方法使用的是自然排序对元素进行排序的

     自然排序,就是让元素所属的类实现Comparable接口,重写compareTo​(T o)方法     重点:如何重写方法

    java-集合-set(不重复集合)知识分解——庖丁解牛版

    重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写     重点:主要条件与次要条件

    用TreeSet集合存储自定义对象,带参构造方法使用的是比较器排序对元素进行排序的

     比较器排序,就是让集合构造方法接收Comparator的实现类对象,重写compare​(T o1,T o2)方法

    重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写

    3、代码展示(比较器排序)

    package SetDemo;
    
    import java.util.COMparator;
    import java.util.HashSet;
    import java.util.Set;
    import java.util.TreeSet;
    
    public class Set003 {
        public static void main(String[] args) {
    
            Set<News> set=new TreeSet<News>(new Comparator<News>() {
                @override
                public int compare(News n1, News n2) {
                    int num=n1.getTitle().compareTo(n2.getTitle());
                    return num;
                }
            });
    
            News news1=new News("中国多地遭雾霾笼罩空气质量再成热议话题");
            News news2=new News("民进党台北举行“火大游行”");
            News news3=new News("春节临近北京“卖房热”");
            News news4=new News("春节临近北京“卖房热”");
    
            System.out.println("新闻一与新闻二的比较:"+news1.equals(news2));
            System.out.println("新闻三与新闻四的比较:"+news3.equals(news4));
            System.out.println("--------");
            set.add(news1);
            set.add(news2);
            set.add(news3);
            set.add(news4);
    
            for (int i = 0; i < set.size(); i++) {
    
            }
    
            Set<News> set1=new HashSet<News>();
            set1.addAll(set);
    
            for (News n:set1){
                System.out.println(n);
            }
            System.out.println("--------");
    
    
            System.out.println("集合中新闻的长度为:"+set1.size());
    
    
    
        }
    }

    第三重境界:官知止而神欲行

    1、哈希值(hashCode)

    概念:

           是Jdk根据对象的地址/String/数字算出来一串数字(int),hashCode()是Object类的方法,所以说Java的对象都可以调用这个hashCode方法返回哈希值。

    特点:

           (1)如果自定义类没有重写hashCode方法,那么自定义类的对象生成的哈希值是根据对象的内存地址值生成的,所以说即便两个对象的属性一样,哈希值也不一样。        (2)诉求:如果两个对象属性一样,那么两个对象哈希值也要一样,所以在自定义的类中重写了      hashCode方法(不调用Object类hashCode),是根据对象的属性生成哈希值。        (3)两个对象哈希值一样,不代表两个对象的属性一样.两个对象的属性一样,则两个对象的哈希值肯定一样。        (4)数字的哈希值是它本身。

    代码展示:

    public static void main(String[] args) {
            
            //创建学生类对象,实例化
            Student s1 = new Student02("盘古大神", 100, 100, 100,300);
            Student s2 = new Student02("女娲娘娘", 100, 95, 90,285);
            Student s3 = new Student02("天皇伏羲", 98, 100, 90,288);
            Student s4 = new Student02("地皇神农", 99, 95, 90,284);
            Student s5 = new Student02("人皇轩辕", 95, 98, 80,273);
               
            //输出哈希值
            System.out.println(s1.hashCode());
            System.out.println(s2.hashCode());
            System.out.println(s3.hashCode());
            System.out.println(s4.hashCode());
            System.out.println(s5.hashCode());
    
    
        }
    
    //输出结果
    
    356573597
    1735600054
    21685669
    2133927002
    1836019240
    
    Process finished with exit code 0

    2、哈希表

    概念:

    散列表Hash table,也叫哈希表),是根据键(Key)而直接访问在内存存储位置的数据结构。也就是说,它通过计算一个关于键值的函数,将所需查询的数据映射到表中一个位置来访问记录,这加快了查找速度。这个映射函数称做散列函数,存放记录的数组称做散列表

    哈希表的实现:

    实现哈希表我们可以采用两种方法:

    1、数组+链表

    2、数组+二叉树

    哈希表的优缺点:

    优点:

    1. 无论数据有多少,处理起来都特别的快
    2. 能够快速地进行 插入修改元素 、删除元素 、查找元素 等操作
    3. 代码简单(其实只需要把哈希函数写好,之后的代码就很简单了)

    缺点:

    1. 哈希表中的数据是没有顺序的
    2. 数据不允许重复

    哈希表的学习:

    如果大家想再深入学习哈希表的知识,下附链接:

    数据结构 Hash表(哈希表)_积跬步 至千里-CSDN博客_哈希表

     ending!!!!!

    java-集合-set(不重复集合)知识分解——庖丁解牛版

    脚本宝典总结

    以上是脚本宝典为你收集整理的java-集合-set(不重复集合)知识分解——庖丁解牛版全部内容,希望文章能够帮你解决java-集合-set(不重复集合)知识分解——庖丁解牛版所遇到的问题。

    如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

    本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
    如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。