zoukankan      html  css  js  c++  java
  • Java基础(十七)——Set集合、可变参数和Collections工具类

    Set接口

      java.util.set接口和java.util.List接口是一样的,都是继承自Collection接口,它与collection接口中的方法基本一样,没有对Collection接口进行功能上的扩展,只是比Collection接口更加严格。与List接口不同的是,Set接口中的元素是无序的,并且都会以某种规则保证存入的元素不重复。

      Set集合取出元素的方式可以采用:迭代器、增强for循环。

    HashSet集合介绍

      java.util.HashSet是Set接口的一个实现类,它存储的元素是不可重复的,并且元素都是无序的(存取顺序不一致)。java.util.HashSet底层的实现其实是一个java.util.HashMap支持的。

      HashSet是根据对象的哈希值来确定元素在集合当中的存储位置,因此它具有良好的存取和查找性能。保证元素唯一性的方式依赖于hashCodeequals方法。

      实例代码:

     1         //创建HashSet集合对象
     2         HashSet<String> hashSet = new HashSet<>();
     3         String str01 = new String("abc");
     4         String str02 = new String("abc");
     5         hashSet.add(str01);
     6         hashSet.add(str02);
     7         hashSet.add("种地");
     8         hashSet.add("通话");
     9         hashSet.add("abc");
    10         System.out.println(hashSet);//[通话, abc, 种地]
    11         //依赖于hashCode和equals方法
    12  

    HashSet集合存储数据的结构(哈希表)

      什么是哈希表呢?

      在JDK1.8之前,哈希表的底层采用的是数组+链表实现,即使用链表处理哈希冲突,同一哈希值的链表都存储在一个链表里,但是当位于一个链中的元素较多时,即hash值相等的元素较多时,通过key值依次查找的效率很低下。在JDK1.8中,哈希表存储结构采用数组+链表/红黑树实现的,当链表的长度超过阈值(8)时,将链表转换成红黑树结构,这样的好处是大大减少了查找的时间。

      如图展示:

    哈希表结构概述

      总而言之,JDK1.8之后引入红黑树结构大大优化了HashMap的性能,那么对于我们来讲保证HashSet元素唯一不重复,其实是根据对象的hashCode和equals方法来决定的。如果我们往集合当中存储的是自定义的对象,需要保证对象的唯一性,就必须重写hashCode和equals方法,来自定义当前的对象的比较方式。

      HashSet保证元素唯一的原理,如图所示

    HashSet保证元素唯一的原理介绍

     HashSet存储自定义类型的元素

        一般需要重写对象当中的hashCode和equals方法,建立自己的比较方式。才能保证HashSet集合中元素的唯一性。

      代码示例:

     1 @Override
     2     public boolean equals(Object o) {
     3         if (o == null) {
     4             return false;
     5         }
     6         if (this == o) {
     7             return true;
     8         }
     9         // 向下转型 类型判断
    10         if (o instanceof Student) {
    11             Student student = (Student)o;
    12             // 同名同年龄的人为同一个人 true
    13             return student.getName().equals(name) && student.getAge() == age;
    14         }
    15         return false;
    16     }
    17 
    18     @Override
    19     public int hashCode(){
    20          // 使用Objects类中的hash方法
    21         return Objects.hash(name,age);
    22     }

    LinkedHashSet集合

       我们知道HashSet保证元素的唯一,可是存进去的元素是没有顺序的,那么如何保证存进去的元素是有序的?

      在java.util.HashSet类的下面还有一个子类java.util.LinkedHashSet,它是链表和哈希表的组合的一个数据存储结构。代码示例:

        

     1 // 构建一个LinkedHashSet集合对象
     2         LinkedHashSet<String> linkedHashSet = new LinkedHashSet<>();
     3         linkedHashSet.add("www");
     4         linkedHashSet.add("baidu");
     5         linkedHashSet.add("com");
     6         linkedHashSet.add("abc");
     7         linkedHashSet.add("abc");
     8         linkedHashSet.add("java");
     9         linkedHashSet.add("python");
    10         // [www, baidu, com, abc, java, python]
    11         System.out.println(linkedHashSet);// [www, baidu, com, abc] 有序的,不重复的

    可变参数

       在JDK1.5之后,如果我们定义一个方法需要接受多个参数,并且多个参数的数据类型一致,那么我们可以简化成如下格式:

    1 修饰符 返回值类型  方法名(参数类型... 形参名){
    2     //...
    3 }

      其实上面的格式完全等价于:

    1 修饰符 返回值类型  方法名(参数类型[] 参数名){
    2     //....
    3 }

      只是后面的写法,在方法调用,必须传递一个数组类型,而前者可以直接传递参数数据。

      JDK1.5之后,出现的这种简化操作。"..."用在参数上,我们称之为可变参数。

      同样是代表数组,但是在方法调用这个带有可变参数时,不用创建数组,而是直接将数组当中的元素作为实际参数进行传递,其实编译生成的.class文件,本质是将这些元素封装到了一个数组当中,再进行数据传递,这些动作都在编译生成.class文件的时候,自动完成了。

      代码示例:

    1  public static void add(int... arr) {
    2         //System.out.println(arr);// [I@1b6d3586 底层就是一个数组
    3         //System.out.println(arr.length);//0
    4         int sum = 0;
    5         for (int i = 0; i < arr.length; i++) {
    6             sum += arr[i];
    7         }
    8         System.out.println(sum); // 30
    9     }

      Collections集合工具类

        常用功能

     

    • java.util.Collections是集合工具类,用来操作集合对象中的元素, 方法如下:
    • public static <T> boolean addAll(Collection<? super T> c,T... elements):往集合中一次性添加多个元素。
    • public static <T> void shuffle(List<?> list):打乱集合中的元素顺序。
    • public static <T> void sort(List<T> list):将集合中的元素按照默认规则排序。
    • public static <T> void sort(List<T> list,Comparator<? super T> c):将集合中的元素按照指定的规则进行排序。

    代码演示:

      

     1         ArrayList<String> strs = new ArrayList<>();
     2         //往集合当中存储元素
     3         /*strs.add("abc");
     4         strs.add("小孙");
     5         strs.add("小刘");
     6         strs.add("小赵");*/
     7 
     8         //使用Collections集合工具类中的addAll
     9         Collections.addAll(strs, "张三","老王","小金豆","孬蛋","老白干");
    10         System.out.println(strs);
    11         System.out.println("=========================");
    12         Collections.shuffle(strs);
    13         System.out.println(strs);    
     1 ArrayList<Integer> list01 = new ArrayList<>();
     2 Collections.addAll(list01, 124,234,566,324,765,342);
     3 System.out.println(list01);
     4        System.out.println("============================");
     5 Collections.sort(list01);
     6 System.out.println(list01);
     7         System.out.println("============================");
     8 ArrayList<String> list02 = new ArrayList<>();
     9         Collections.addAll(list02,"asd","sd","sc","sv","ac","b","vc","v","cs");
    10 Collections.shuffle(list02);
    11 Collections.sort(list02);
    12 System.out.println(list02);
  • 相关阅读:
    C#编程思路
    将字符串类型字段转为map类型字段,使用str_to_map()函数
    写hive脚本时,如果hive的过滤条件比较多。可以把过滤条件放到一个参数里。然后把参数放到过滤条件处。这样以后只需要改参数就可以了
    linux中. 路径/文件
    inner join ,left join 会导致数据发散
    如何批量按分区插入数据
    hive表添加字段后,查不出数据是咋回事?
    linux中$0的含义
    linux中的$#含义
    linux的语法
  • 原文地址:https://www.cnblogs.com/lk625/p/14083060.html
Copyright © 2011-2022 走看看