当前位置: 首页 > news >正文

Java 进阶集合Set、Map(二)

文章目录

  • 一、Set集合
    • 1、HashSet集合
      • 1)原理
      • 2)组成
      • 3)哈希值
      • 4)哈希值特点
      • 5)jdk8哈希表流程:
    • 2、LinkedHashSet集合
      • 1)概述
      • 2)原理
    • 3、TreeSet集合
      • 1)默认规则
      • 2) 自定义规则
    • 4、可变参数(动参)
  • 二、Map集合
    • 1、概述
    • 2、特点
    • 3、常用API
    • 4、HashMap 用的最多
    • 5、LinkedHashMap
    • 6、TreeMap

一、Set集合

1、HashSet集合

1)原理

底层采用哈希表存储数据

2)组成

jdk8之前:底层数组+链表组成
jdk8之后:底层数组+链表+红黑树组成

3)哈希值

对象的内存地址经过处理后的结构,由于每个对象的内存地址都不一样,所以哈希码也不一样。更重要的是:这里的内存地址是JVM虚拟机虚拟出来的地址,并不是真实的物理内存地址

4)哈希值特点

同一个对象多次调用hashCode()方法返回的哈希值是相同的
默认情况下,不同对象的哈希值是不同的

5)jdk8哈希表流程:

Constructs a new, empty set; the backing HashMap instance has default initial capacity (16) and load factor (0.75).

创建一个新的空集合,默认初始值是16,加载因子(0.75)
根据元素的哈希值和数组的长度计算出应存入的位置
首先判断当前位置是否为NULL,空则直接存入,非空则equals方法比较属性值,相同则不存,不同则存入数组
当数组存储满足16*0.75=12时自动扩容,每次扩容会是当前容量的2倍
在这里插入图片描述

import java.util.HashSet;

public class ClassStructure {
    public static void main(String[] args) {
        HashSet<String> set = new HashSet<>();
        set.add("aa");
        set.add("bb");
        set.add("cc");
        set.add("aa");
        set.add("ee");
        set.add("ff1");
        set.add("ff2");
        set.add("ff3");
        System.out.println(set);
        //哈希值
        System.out.println(set.hashCode());
    }
}

2、LinkedHashSet集合

1)概述

有序、不重复、无索引
有序指保证存储和取出元素顺序一致

2)原理

底层数据结构哈希表,每个元素增加双链表机制记录数据存储顺序
在这里插入图片描述
在这里插入图片描述

import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;

public class ClassStructure {
    public static void main(String[] args) {
        Set set = new LinkedHashSet<>();
        set.add("aa");
        set.add(123);
        set.add(456);
        set.add("hello");
        System.out.println(set);
    }
}


3、TreeSet集合

不重复、无索引、可排序
可排序:按照元素的大小默认升序(有小到大)排序。
TreeSet集合底层是基于红黑树的数据结构实现排序的,增删改查性能都较好。

注意:TreeSet集合是一定要排序的,可以将元素按照指定的规则进行排序

1)默认规则

对于数值类型:Integer , Double,默认升序排序。
对于字符串类型:默认按照首字符的编号升序排序。
对于自定义类型对象,TreeSet无法直接排序。

2) 自定义规则

TreeSet集合有参数构造器,可以设置Comparator接口对应的比较器对象,来定制比较规则。
在这里插入图片描述

public class Student {
    private int id;
    private String name;
    private int age;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;

public class ClassStructure {
    public static void main(String[] args) {
        Student stu = new Student();
        stu.setId(1);
        stu.setName("zhangsan");
        stu.setAge(11);
        Student stu1 = new Student();
        stu1.setId(3);
        stu1.setName("zhangsan3");
        stu1.setAge(33);
        Student stu2 = new Student();
        stu2.setId(2);
        stu2.setName("zhangsan2");
        stu2.setAge(22);
        Student stu3 = new Student();
        stu3.setId(5);
        stu3.setName("zhangsan5");
        stu3.setAge(55);
        Set<Student> set = new TreeSet<>(
                new Comparator<Student>() {
                    @Override
                    public int compare(Student o1, Student o2) {
                        return o1.getId()-o2.getId();
                    }
                }
        );
        set.add(stu);
        set.add(stu1);
        set.add(stu2);
        set.add(stu3);
        for (Student id:set){
            System.out.println(id);
        }
    }
}


让自定义的类,实现Comparable接口重写里面的compareTo方法来定制比较规则。

在这里插入图片描述

public class Student implements Comparable<Student>{
    private int id;
    private String name;
    private int age;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    /*
    默认升序
     */
    @Override
    public int compareTo(Student o) {
        return this.id - o.id;
    }
}

import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;

public class ClassStructure {
    public static void main(String[] args) {
        Student stu = new Student();
        stu.setId(1);
        stu.setName("zhangsan");
        stu.setAge(11);
        Student stu1 = new Student();
        stu1.setId(3);
        stu1.setName("zhangsan3");
        stu1.setAge(33);
        Student stu2 = new Student();
        stu2.setId(2);
        stu2.setName("zhangsan2");
        stu2.setAge(22);
        Student stu3 = new Student();
        stu3.setId(5);
        stu3.setName("zhangsan5");
        stu3.setAge(55);
        Set<Student> set = new TreeSet<>();
        set.add(stu);
        set.add(stu1);
        set.add(stu2);
        set.add(stu3);
        for (Student id:set){
            System.out.println(id);
        }
    }
}


4、可变参数(动参)

  • 定义

可变参数用在形参中可以接收多个数据。
可变参数的格式:数据类型…参数名称

  • 作用

接收参数非常灵活,方便。可以不接收参数,可以接收1个或者多个参数,也可以接收一个数组
可变参数在方法内部本质上就是一个数组。

  • 注意

一个形参列表中可变参数只能有一个
可变参数必须放在形参列表的最后面

  • 题目(实战),需求:

假如需要定义一个方法求和,该方法可以灵活的完成如下需求:
计算1个数据的和。
计算2个数据的和。
计算3个数据的和。
计算n个数据的和,甚至可以支持不接收参数进行调用。

在这里插入图片描述

public class ClassStructure {

    public static void Test(Integer... args) {
        int sum = 0;
        for (int ag : args) {
            sum += ag;
        }
        System.out.println(sum);
    }

    public static void main(String[] args) {
        Test(1);
        Test(1, 2);
        Test(1, 2, 3);
    }
}


二、Map集合

1、概述

Map是双列集合,每个元素包含两个数据,格式(Key=Value),也称为键值对集合

2、特点

Map集合的键是无序,不重复的,无索引的,值不做要求(可以重复)
Map集合后面重复的键对应的值会覆盖前面重复键的值,键值对都可以为null。

3、常用API

方法名解释
V put(K key,V value) 添加元素
V remove(Object key) 根据键删除键值对元素
void clear() 清空所有的键值对元素
int size() 集合的长度,集合中键值对的个数
boolean containsKey(Object key) 判断集合是否包含指定的键
boolean containsValue(Object value) 判断集合是否包含指定的值
boolean isEmpty() 判断集合是否为空

4、HashMap 用的最多

元素按照键是无序,不重复,无索引,值不做要求(可以重复)

-实战根据key求value
在这里插入图片描述

import java.util.HashMap;
import java.util.Map;

public class ClassStructure {
    public static void main(String[] args) {
        Map<Integer,String> map = new HashMap<>();
        map.put(1,"数学");
        map.put(2,"语文");
        map.put(3,"英语");
        map.put(4,"物理");
        map.put(5,"政治");
        String str = map.get(1);
        System.out.println(str);
        String str1 = map.get(3);
        System.out.println(str1);
    }
}

5、LinkedHashMap

元素按照键是有序,不重复,无索引,值不做要求

  • 实战 判断key是否存在
    在这里插入图片描述
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

public class ClassStructure {
    public static void main(String[] args) {
        Map<Integer,String> map = new LinkedHashMap<>();
        map.put(1,"数学");
        map.put(2,"语文");
        map.put(3,"英语");
        map.put(4,"物理");
        map.put(5,"政治");
        boolean str = map.containsKey(1);
        System.out.println(str);
        boolean str1 = map.containsKey(6);
        System.out.println(str1);
    }
}

6、TreeMap

元素按照建是排序,不重复,无索引的,值不做要求

  • 实战 参考TreeSet
    Set系列集合的底层就是Map实现的,只是Set集合中的元素只要键数据

相关文章:

  • 2022-Docker常用命令
  • Spring中事务传播特性(Propagation)
  • Matlab:Matlab编程语言应用之数学统计(柱状图、曲线分析等)的使用方法简介、案例实现之详细攻略
  • YOLOv7改进之二十五:引入Swin Transformer
  • 03 nginx 是如何自动推导文件的 content-type 的
  • Java 8 Stream 从入门到进阶——像SQL一样玩转集合
  • C++STL详解(五)mapset的使用及其模拟实现
  • 串口通信-USART和UART的区别
  • Docker常见操作
  • YOLOV7详细解读(一)网络架构解读
  • 【侯捷C++-----STL与泛型编程】
  • es6对象的扩展、对象的新增方法
  • Stream流
  • DRM系列(8)之prepare_signaling
  • 企业级C++项目那些事(1):VSQt相关设置
  • 【Linux系统编程】快速查找errno错误码信息
  • 5分钟即可掌握的前端高效利器:JavaScript 策略模式
  • Java方法详解
  • Odoo domain写法及运用
  • Webpack 4 学习01(基础配置)
  • windows下如何用phpstorm同步测试服务器
  • 闭包--闭包作用之保存(一)
  • 编写高质量JavaScript代码之并发
  • 构造函数(constructor)与原型链(prototype)关系
  • 简单基于spring的redis配置(单机和集群模式)
  • 简析gRPC client 连接管理
  • 京东美团研发面经
  • 聊聊flink的BlobWriter
  • 面试遇到的一些题
  • 时间复杂度与空间复杂度分析
  • 微服务核心架构梳理
  • 学习HTTP相关知识笔记
  • Prometheus VS InfluxDB
  • ​【C语言】长篇详解,字符系列篇3-----strstr,strtok,strerror字符串函数的使用【图文详解​】
  • #1015 : KMP算法
  • #mysql 8.0 踩坑日记
  • $forceUpdate()函数
  • (26)4.7 字符函数和字符串函数
  • (3)(3.5) 遥测无线电区域条例
  • (done) NLP “bag-of-words“ 方法 (带有二元分类和多元分类两个例子)词袋模型、BoW
  • (solr系列:一)使用tomcat部署solr服务
  • (ZT) 理解系统底层的概念是多么重要(by趋势科技邹飞)
  • (多级缓存)缓存同步
  • (附源码)spring boot儿童教育管理系统 毕业设计 281442
  • (一)C语言之入门:使用Visual Studio Community 2022运行hello world
  • (转)Scala的“=”符号简介
  • ***利用Ms05002溢出找“肉鸡
  • .net mvc 获取url中controller和action
  • .NET MVC第三章、三种传值方式
  • .NET 服务 ServiceController
  • .Net程序帮助文档制作
  • .NET应用架构设计:原则、模式与实践 目录预览
  • .pop ----remove 删除
  • @SpringBootApplication 包含的三个注解及其含义
  • [1525]字符统计2 (哈希)SDUT