IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 【小白学Java】D23 》》》set集合 & HashSet集合 & 哈希值& LinkedHashSet集合 &TreeSet集合&可变参数 -> 正文阅读

[Java知识库]【小白学Java】D23 》》》set集合 & HashSet集合 & 哈希值& LinkedHashSet集合 &TreeSet集合&可变参数

了解Set集合

??????????Set接口和List接口一样,都是在java.util包下,它们都是继承自Collection接口,Set接口中的方法与Collection接口中的方法基本上是一致的。Set集合并没有对collection 接口进行功能上的扩充,它只是比 Collection 接口更加的严格了些。Set接口与List接口不同点,在于Set 接口中的元素数据是无序的,而且会以某种规则来保证存储的元素数据不会出现重复。

??????????Set集合有多个子类,其中包括有HashSet 、和LinkedHashSet,这两个集合使用的较多。

??????????因为Set集合是无序的,没有索引也没有带索引的方法,所以要取出Set集合中的元素数据,可以使用迭代器或者增强for循环的方式,而不能使用普通的for循环。

所以做总结道Set集合的两大特点:

  • 1.Set集合中不允许存储重复的元素
  • 2.Set集合没有紊引,也没有带素引的方法,不能使用昔通的for循环遍历

HashSet集合

Hashset集合也是java.util包下的,它实现了(impLements) Set接口

HashSet集合的特点:

  • 1.HashSet集合中不允许存储重复的元素数据
  • 2.HashSet集合没有素引,同时也没有带索引的方法,不能使用昔通的for循环进行遍历
  • 3.HashSet集合是一个无序的集合,它的存储元素和取出元素的操作的顺序可能会不一致
  • 4.HashSet集合的底层为哈希表结构,哈希表的特点就是查找的速度非常的快。
//创建一个set集合,使用多态
Set<String> set=new HashSet<>();
//向集合中添加元素
set.add("a");
set.add("b");
set.add("c");
set.add("d");
set.add("e");
set.add("b");
//打印set集合
System.out.println(set);
//打印结果为:[a, b, c, d, e] set集合不存储重复的元素

哈希值

概述:

哈希值为十进制整数,由系统随机给出的。哈希值指就是对象的地址值,是逻辑地址,是一个模拟出来的地址而不是数据元素实际存储时的物理地址。

那么如何获取哈希值呢?
在java.lang.0bject类有一个方法,可以获取对象的哈希值,如下图:
在这里插入图片描述

通过以下代码来了解下哈希值

//创建一个person类
class people {
    private String name;
    private int age;
    private String sex;
    private double high;
}
public class hashcode{
    public static void main(String[] args) {
        //new一个对象,获取其hashcode,打印
        people people1 = new people();
        int hashCode1 = people1.hashCode();
        System.out.println(hashCode1);//1163157884

        people people2 = new people();
        int hashCode2 = people2.hashCode();
        System.out.println(hashCode2);//1956725890


/*java.lang.Object类的toString()方法
* public String toString() {
       return getClass().getName() + "@" + Integer.toHexString(hashCode());
   }
* */
        //打印两个对象的地址值
        System.out.println(people1);
        //com.sj.javabase.Set.person@4554617c
        System.out.println(people2);
        //com.sj.javabase.Set.person@74a14482

    }

}

在这里插入图片描述在这里插入图片描述

详细了解HashSet集合存储数据的结构

Hashcode(哈希值)的作用其实就是用来表示对象的地址,那么HashSet集合是如何存储元素的呢?
????首先,HashSct集合存储数据的结构是哈希表(哈希表的特点就是速度快)。在JDK1.8版本之前,哈希表是由数组加链表组成的;而在,JDK1.8版本之后,哈希表是由数组加上链表或者是由数组加上红黑树组成的(红黑树的作用就是提高查询的速度,红黑树采用折半查找,查找元素非常的快)。哈希表采用数组结构的目的就是分组,把哈希值相同的元素分为一组;使用链表的目的就是连接,把哈希值相同的元素连接起来;当链表的长度超过了8位,那么就会采用红黑树,其目的就是为了提高查找速度。

在这里插入图片描述

详细解析Set集合为什么不允许存储重复的元素数据

看一个例子:


import java.lang.String;
import java.util.HashSet;

public class demohashset {
    public static void main(String[] args) {
        //创建一个hashset集合
        HashSet<String> set = new HashSet<>();

        //new两个字符串,并打印哈希值
        String s1 =new String("abc") ;
        int hashCode1 = s1.hashCode();
        System.out.println("s1:hashcode\t"+hashCode1);

        String s2 =new String("abc") ;
        int hashCode2 = s2.hashCode();
        System.out.println("s1:hashcode\t"+hashCode2);

        //打印”重地“”通话“”abc“三个元素的字符串
        int hashCode3 = "重地".hashCode();
        System.out.println("重地:hashcode\t"+hashCode3);

        int hashCode4 = "通话".hashCode();
        System.out.println("通话:hashcode\t"+hashCode4);

        int hashCode5 = "abc".hashCode();
        System.out.println("abc:hashcode\t"+hashCode5);

        //将上面元素添加到集合中去
        set.add(s1);
        set.add(s2);
        set.add("重地");
        set.add("通话");
        set.add("abc");

        //打印集合
        System.out.println(set);
        //打印结果[重地, 通话, abc] 
        //发现:集合存入和取出顺序不一致,不允许存储重复元素
    }
}

运行结果截图:
在这里插入图片描述
现在我们来分析下Set集合不允许存储重复元素的原理:

有个小前提:
Set集合中存储的元素必须要重写hashcode()方法和equals()方法

原理
????Set集合在调用add()方法向集合中添加元素时,会调用hashcode()方法来计算所要添加元素的哈希值,其次还可能调用equals()方法来判断相同的哈希值的元素数据的值是否相等

下面根据上面例子,详细的分析下Set集合存储元素的运行过程:

第一步先看s1;
????Set集合中的add()方法,首先,会调用s1的hashcod()方法,来计算s1的字符串 “abc” 的哈希值,得到哈希值为96354,随后,在集合中查找有没有96354这个哈希值的元素,发现集合中没有,那么,就会把sl的字符串存储到集合中。

第二步看s2;
????Set集合中的add()方法,首先,会调用s2的hashcod()方法,来计算s2的字符串 “abc” 的哈希值,得到哈希值为96354,随后,在集合中查找有没有哈希值为96354的元素,发现有,那么,就会在调用equals()方法来与哈希值相同的元素进行比较,方法返回值为true,那么就会认定这两个元素相同,最终,就不会把s2的字符串存储到集合中。

第三步看”重地“;
????Set集合中的add()方法,首先,会调用”重地“的hashcod()方法,计算字符串 ”重地“ 的哈希值,得到哈希值为1179395,随后,在集合中查找有没有哈希值为1179395的元素,发现没有,就会把”重地“存储到集合中。

第四步看”通话“;
????Set集合中的add()方法,首先,会调用”通话“的hashcod()方法,来计算字符串 ”通话“的哈希值,得到哈希值为1179395,随后,在集合中查找有没有哈希值为1179395的元素,发现有,那么,就会再调用equals()方法来与哈希值相同的元素进行比较,方法返回值为false,那么就会认定这两个元素不相同,最终就会把”通话存储到集合中。

注意:若是要使用HashSet集合来存储自定义的元素数据(例如,自定义的类的对象等),那么就一定要重写hashcode()方法和equals()方法


LinkedHashSet集合

LinkedHashSett集合也是java.util包下的,不过它是继承了HashSet集合。

LinkedHashSet集合特点:
????????LinkedHashSet集合的底层是一个哈希表加上一个链表组成,也就是说LinkedHashSet集合比HashSet集合多了一条链表用来记录元素的存储顺序的链表,从而保证了元素有序性。

//创建一个HashSet集合
HashSet<String> set = new HashSet<>();
set.add("jdbc");
set.add("java");
set.add("mysql");
set.add("java");
set.add("hadoop");
System.out.println(set);

//创建一个LinkedHashSet集合
LinkedHashSet<String> linkedHashSet = new LinkedHashSet<>();
linkedHashSet.add("jdbc");
linkedHashSet.add("java");
linkedHashSet.add("mysql");
linkedHashSet.add("java");
linkedHashSet.add("hadoop");
System.out.println(linkedHashSet);

在这里插入图片描述

可变参数

????????可变参数是JDK1.5之后出现的新的特性,它的底层是一个数组,数组的容量会根据传递的参数的个数来创建不同长度的数组,传递的参数个数可以是0个参数(不传递参数),或者是多个参数。

使用可变参数的前提:
????????当方法的参数列表中,参数的数据类型确定但参数的个数不确定时,方可使用可变参数。

使用格式:
	修饰符 返回值类型 方法名(数据类型...变量名);
	//在定义方法的时候使用

注意:

  • 1.一个方法的参数列表,只能有一个可变参数
  • 2.如果方法的参数有多个,那么可变参数必须写在参数列表的未尾
public static void main(String[] args) {
    //调用方法sum
    int a = sum(3,5,6,8,10);
    System.out.println(a);

}
public static int sum(int...var){
    System.out.println("var:\t"+var);
    //打印的为[I@4554617c 数组的地址值,底层为一个数组
    System.out.println("var.length:\t"+var.length);
    //打印数组长度
    System.out.println("**累加求和**");
    int  s = 0;
    for (int i: var){
        s+=i;
    }
    return s;
}

在这里插入图片描述

TreeSet集合

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-07-16 11:08:15  更:2021-07-16 11:08:34 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/5 7:23:15-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码