Java 集合 - Map 接口

news2024/11/28 16:40:39

文章目录

    • 1.概述
    • 2.常用 API
    • 3.遍历 Map 集合
    • 4.HashMap 和 Hashtable
    • 5.LinkedHashMap
    • 6.TreeMap
    • 7.Properties
    • 8.Set 集合与 Map 集合的关系
    • 9.总结

1.概述

在日常生活和编程中,我们常常需要处理一种特殊的关系:一一对应的关系,如 IP 地址与主机名,身份证号与个人信息,系统用户名与系统用户对象等。这种关系被称为映射,在 Java 中,我们使用 Map<K, V> 接口来表达和处理这种关系。

java.util.Map<K, V> 是一个在 Java 集合框架中用于存储键值对的接口。键和值是一一对应的,键用于唯一标识一个元素,值则是与该键关联的数据。通过键,我们可以非常快速地找到其对应的值,这就是映射的核心特性。

相比于 Collection<E> 接口,Map<K, V> 接口有着根本的区别。Collection<E> 接口的实现类,如 List<E>Set<E>,存储的是一组独立的元素。元素之间没有特定的关系,只是单纯地放在一起。而 Map<K, V> 接口则不同,它的元素以键值对的形式存在,每个元素由一个键和一个值组成,二者之间存在着一种映射关系。基于此,我们通常将 Collection<E> 的实现类称为单列集合,而将 Map<K, V> 的实现类称为双列集合。

Map 接口中,每个键都必须是唯一的,即不允许重复的键存在。然而,对于值则没有这个限制,相同的值可以与不同的键关联。另外,每个键只能映射到一个值,但这个值可以是单一的值,也可以是一个数组或集合,这为存储复杂的数据结构提供了可能。

2.常用 API

方法名描述
put(K key, V value)将指定的键值对添加到 Map 中
get(Object key)返回指定键所映射的值
remove(Object key)从 Map 中移除指定键及其对应的值
clear()移除 Map 中的所有键值对
containsKey(Object key)判断 Map 是否包含指定的键
containsValue(Object value)判断 Map 是否包含指定的值
keySet()返回 Map 中所有键的集合
values()返回 Map 中所有值的集合
entrySet()返回 Map 中所有键值对的集合
size()返回 Map 中键值对的数量
isEmpty()判断 Map 是否为空
equals(Object o)判断 Map 是否与指定对象相等
hashCode()返回 Map 的哈希码值

TIP:

使用 put 方法时,若指定的键(key)在集合中不存在,则没有这个键对应的值,返回 null,并把指定的键值添加到集合中; 若指定的键 (key) 在集合中存在,则返回值为集合中键对应的值(该值为替换前的值),并把指定键所对应的值,替换成指定的新值。

下面是一个简单的使用案例:

public class MapTest {
    public static void main(String[] args) {
        // 创建HashMap集合
        Map<String,String> map = new HashMap<>();

        // 添加元素
        map.put("name","张三");
        map.put("age","18");
        map.put("eamil", "XXXX@qq.com");

        // 输出集合
        System.out.println(map); // {name=张三, eamil=XXXX@qq, age=18}

        // 根据key获取value
        System.out.println(map.get("name")); // 张三

        // 根据key删除元素
        map.remove("age");

        // 输出集合
        System.out.println(map); // {name=张三, eamil=XXXX@qq}

        // 判断是否包含某个key
        System.out.println(map.containsKey("name")); // true

        // 判断是否包含某个value
        System.out.println(map.containsValue("张三")); // true

        // 获取所有key
        System.out.println(map.keySet()); // [name, eamil]

        // 获取所有value
        System.out.println(map.values()); // [张三, XXXX@qq]

        // 获取所有key-value
        System.out.println(map.entrySet()); // [name=张三, eamil=XXXX@qq]

        // 返回集合大小
        System.out.println(map.size()); // 2

        // 判断集合是否为空
        System.out.println(map.isEmpty()); // false

        // 清空集合
        map.clear();

        // 判断集合是否为空
        System.out.println(map.isEmpty()); // true
    }
}

3.遍历 Map 集合

遍历集合是我们在日常编程中经常需要进行的操作。对于 Collection 接口的实现类,如 ListSet,我们通常使用 foreach 循环或 Iterator 对象进行遍历。然而,对于 Map 接口,情况则有所不同。

由于 Map 接口没有继承 java.lang.Iterable<T> 接口,也没有实现 Iterator iterator() 方法,所以我们不能直接使用 foreach 循环或 Iterator 对象遍历 Map。不过,我们仍有其他方法可以有效地遍历 Map

Map 接口声名如下:

public interface Map<K, V> {
    // ......
}

一种方法是分别遍历所有的键和值。这种方法的实现非常简单,我们可以直接调用 MapkeySet() 方法和 values() 方法,分别获取所有的键和值,然后再使用 foreach 循环或 Iterator 对象遍历。

单独遍历所有的键:

for (K key : map.keySet()) {
    // 处理键
}

map.keySet().forEach(key -> System.out.println(key));

单独遍历所有的值:

for (V value : map.values()) {
    // 处理值
}

map.values().forEach(value -> System.out.println(value));

另一种方法是成对遍历,即同时遍历键和值。这种方法需要使用 Map 接口的内部接口 Map.Entry<K, V>Map.Entry<K, V> 表示了一个键值对,即 Map 的一个元素。

Map 中,每个元素都是一个 Map.Entry<K, V> 对象,键和值都被存储在这个对象中。因此,我们可以通过遍历所有的 Map.Entry<K, V> 对象,同时获取键和值。

成对遍历所有的键和值:

for (Map.Entry<K, V> entry : map.entrySet()) {
    K key = entry.getKey();
    V value = entry.getValue();
    // 处理键和值
}

map.entrySet().forEach(entry -> System.out.println(entry.getKey() + "=" + entry.getValue()));

下面是一个完整的简单使用实例:

public static void main(String[] args) {
    Map<String,String> map = new HashMap<>();

    map.put("name","张三");
    map.put("age","18");
    map.put("eamil", "xxx@qq.com");

    // 单独遍历key
    map.keySet().forEach(key -> System.out.println(key));

    // 单独遍历value
    map.values().forEach(value -> System.out.println(value));

    // 遍历key-value
    map.entrySet().forEach(entry -> System.out.println(entry.getKey() + "=" + entry.getValue()));
}

4.HashMap 和 Hashtable

HashMapHashtable 是 Java 中两个经典的基于哈希表的数据结构。它们都实现了 Map 接口,可以存储键值对,而且在内部都使用了哈希表以达到快速查找的效果。虽然在表面上它们看起来相似,但在实现细节和用法上,它们有着重要的不同。

HashMap 类图如下:

Hashtable 类图如下:

首先,无论是 HashMap 还是 Hashtable,它们判断两个键是否相等的标准都是:两个键的 hashCode 方法返回值相等,并且它们的 equals 方法返回 true。这是因为哈希表通过哈希函数(在 Java 中是对象的 hashCode 方法)将键映射到内部的数组中,然后通过键的 equals 方法来处理哈希冲突。因此,如果你计划使用自定义对象作为键,你必须正确地重写 hashCodeequals 方法,以确保对象在哈希表中能被正确地存储和查找。

尽管 HashMapHashtable 在判断键相等的方式上相同,但它们在其他方面存在显著的不同。最重要的差异在于并发控制和对 null 的处理。

Hashtable 是线程安全的,它使用了同步机制来保证多线程环境下的正确性。如果你在多线程环境下使用 Hashtable,你可以不用担心并发修改的问题。然而,这种线程安全是有代价的,那就是性能开销。另一方面,Hashtable 不允许使用 null 作为键或值,如果试图插入 null 键或 null 值,Hashtable 会抛出NullPointerException

下面是一个简单的使用案例:

public static void main(String[] args) {
    // 创建Hashtable集合
    Hashtable<String, String> map = new Hashtable<>();

    // 添加元素
    map.put("name", "张三");
    map.put("age", "18");
    // map.put(null,null); // key和value都不可以为null

    // 输出集合
    System.out.println(map); // {name=张三, age=18}
}

与之相反,HashMap 是线程不安全的。如果你在多线程环境下使用 HashMap,并且没有正确地同步,那么可能会遇到并发问题。然而,因为没有同步机制,HashMap 的性能通常比 Hashtable 要好。另外,HashMap 允许使用 null 键和 null 值,这使得它在某些情况下更为灵活。

下面是一个简单的使用案例:

public static void main(String[] args) {
    // 创建HashMap集合
    HashMap<String, String> map = new HashMap<>();

    // 添加元素
    map.put("name", "张三");
    map.put("age", "18");
    map.put(null,null); // key和value都可以为null

    // 输出集合
    System.out.println(map); // {null=null,name=张三, age=18}
}

5.LinkedHashMap

LinkedHashMapHashMap 的一个子类,它在 HashMap 的基础上提供了顺序迭代的能力。这个顺序通常就是元素被插入到映射中的顺序,也被称为插入顺序。此外,LinkedHashMap 还提供了一种称为访问顺序的迭代方式

LinkedHashMap 的类图如下:

LinkedHashMapHashMap 的主要不同之处在于其内部数据结构。在 HashMap 中,每个键值对(即 Map.Entry 对象)都被插入到内部的哈希表中。而LinkedHashMap 中,除了哈希表之外,还维护了一个双向链表。每个 Map.Entry 对象都被插入到这个链表的尾部,形成一个按插入顺序排序的键值对链表

由于这个双向链表的存在,我们可以通过 LinkedHashMap 的迭代器顺序访问每个键值对,这个顺序反映了键值对的插入顺序或访问顺序。插入顺序意味着键值对的迭代顺序就是它们被插入到 LinkedHashMap 中的顺序。而访问顺序则意味着键值对的迭代顺序是它们最后一次被访问(通过 getput 操作)的顺序。

创建 LinkedHashMap 时,我们可以选择使用插入顺序或访问顺序。默认情况下,LinkedHashMap 使用插入顺序。如果我们想要使用访问顺序,只需在创建 LinkedHashMap 时将第三个参数设置为 true 即可。

下面是一个简单使用示例:

public static void main(String[] args) {
    // 创建LinkedHashMap集合(默认情况下按照元素添加的顺序排序)
    Map<String, String> map = new LinkedHashMap<>();

    // 添加元素
    map.put("name", "张三");
    map.put("age", "18");
    map.put(null,null); // key和value都可以为null

    // 输出集合
    System.out.println(map); // {name=张三, age=18, null=null}
}    
public static void main(String[] args) {
    /*
     * 创建LinkedHashMap集合(默认情况下按照元素添加的顺序排序)
     * 当我们不想使用默认的排序方式时,可以使用LinkedHashMap的构造方法
     * LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder)
     * 三个参数:
     * initialCapacity:初始容量,指的是集合初始化时容量
     * loadFactor:加载因子,指的是集合自动扩容的程度
     * accessOrder:排序方式,true表示按照访问顺序排序,false表示按照添加顺序排序
     * 
     * 说明:按照访问顺序排序,指的是按照元素的get方法或put方法访问顺序排序,即最近访问的元素放
     * 在最后,最先访问的元素放在最前。也就是说,当我们每次访问一个元素时,该元素都会被放到最后,
     * 这样就实现了按照访问顺序排序。
     */
    Map<String, String> map = new LinkedHashMap<>(16,0.75f,true);

    // 添加元素
    map.put("name", "张三");
    map.put("age", "18");
    map.put(null,null); // key和value都可以为null

    // 输出集合
    System.out.println(map); // {name=张三, age=18, null=null}

    // 通过get方法访问元素
    map.get("name");
    map.get("age");

    // 再次输出集合
    System.out.println(map); // {null=null, name=张三, age=18}
}

6.TreeMap

TreeMap 是一个强大的 Java 集合类,它实现了 NavigableMap 接口并提供了一种高效的方式来存储键值对,并按照键进行排序。它的内部结构基于一种称为红黑树的自平衡二叉查找树,这使得它在保持键的有序性的同时,能保证关键操作(如插入、删除和查找)的时间复杂度接近于O(log n),其中n是映射中的条目数

其类图如下:

TreeMap 的排序取决于键的自然顺序,或者在创建 TreeMap 实例时提供的 Comparator。自然顺序指的是存储在 TreeMap 中的键所属类的 Comparable 接口的实现,这需要该类的 compareTo 方法定义了一个全序关系。如果键的类没有实现 Comparable 接口,或者你想要在 TreeMap 中使用不同于自然顺序的排序,那么你可以在创建 TreeMap 时提供一个自定义的 Comparator

除了基本的 Map 操作,TreeMap 还提供了一些额外的方法,来利用键的有序性。例如,firstKey 方法可以返回当前映射中的最小键,lastKey 方法可以返回当前映射中的最大键。lowerKey 方法和 higherKey 方法则可以返回给定键的前一个和后一个键。此外,TreeMap 还提供了 subMapheadMaptailMap 方法,可以返回当前映射的一部分视图。

下面是一个简单使用示例:

public static void main(String[] args) {
    // 创建TreeMap集合
    TreeMap<String, String> map = new TreeMap<>();

    // 添加元素
    map.put("name", "张三");
    map.put("age", "18");
    map.put("sex", "男");
    map.put("school", "清华大学");

    // String 实现了Comparable接口,所以TreeMap可以按照 Unicode 码排序
    map.entrySet().forEach(entry -> System.out.println(entry.getKey() + "=" + entry.getValue()));
}
public static void main(String[] args) {
    // 创建LinkedHashMap集合,指定排序规则
    Map<String, String> map = new TreeMap<>(new Comparator<String>(){
        @Override
        public int compare(String o1, String o2) {
            // 按照字符串长度比较(升序)
            return o1.length() - o2.length();
        }
    });


    // 添加元素
    map.put("name", "张三");
    map.put("age", "18");
    map.put("sex", "男");
    map.put("school", "清华大学");

    // 遍历集合
    Set<Entry<String, String>> entries = map.entrySet();
    for (java.util.Map.Entry<String, String> entry : entries) {
        System.out.println(entry.getKey() + "=" + entry.getValue());
    }
}

7.Properties

Properties 类是 Hashtable 子类的一个特殊实例,提供了对持久性键值对存储的支持,其中键和值都是字符串类型。这种结构常常被用于配置文件的读写,尤其是在需要保存和加载程序设置或配置数据的场合。

其类图如下:

Properties 类的一个重要特性是其与流的交互能力。这种能力通过 loadstore 方法来实现。load 方法可以从输入流(如文件输入流)中读取属性列表,而 store 方法则可以将属性列表写入到输出流。这两个方法使得 Properties 对象可以轻松地保存到文件或从文件中加载,非常适合持久化设置和配置数据。

在操作 Properties 对象时,推荐使用 setPropertygetProperty 方法。setProperty 方法用于插入或修改键值对,它接受两个字符串参数,分别代表键和值。getProperty 方法则用于根据键来获取对应的值,它接受一个字符串参数代表键,如果键存在则返回对应的值,否则返回 null

除此之外,Properties 类还提供了一些其他有用的方法。例如,propertyNames 方法可以返回所有键的枚举,stringPropertyNames 方法则可以返回所有键的字符串集合。list 方法可以将属性列表打印到指定的输出流,这对于调试和日志记录非常有用。

下面是一些简单使用案例:

public static void main(String[] args) {
    // 使用 System.getProperties() 方法获取系统属性集
    Properties properties = System.getProperties();

    // 获取系统属性集中的编码
    String encoding = properties.getProperty("file.encoding");

    // 输出编码
    System.out.println(encoding);
}
public static void main(String[] args) {
    // 创建Properties集合
    Properties properties = new Properties();

    // 添加元素
    properties.setProperty("name", "张三");
    properties.setProperty("age", "18");

    // 输出集合
    System.out.println(properties); // {name=张三, age=18}
}

8.Set 集合与 Map 集合的关系

在 Java 的集合框架中,Set 接口的各个实现其实是建立在 Map 接口实现的基础上的。这是由于 SetMap 之间的基本关系:Set 是不包含重复元素的集合,而 Map 则是键值对的集合,且键是唯一的。因此,我们可以将 Set 视为只有键的 Map

具体来说,HashSetTreeSetLinkedHashSet 都是 Set 接口的主要实现,它们分别基于 HashMapTreeMapLinkedHashMap 构建。

HashSet 是最常用的 Set 实现,它的内部就是一个 HashMap 实例。在这个 HashMap 中,HashSet 的元素作为键,值则是一个固定的 Object 对象,因为对于 Set 来说,我们只关心键,不关心值。

关键部分源码如下:

public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable{
    private static final Object PRESENT = new Object();
    
    public HashSet() {
        map = new HashMap<>();
    }
    
    public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }
}

TreeSet 的内部实现是 TreeMap,它是一个有序的 Set,能确保元素按照自然顺序或自定义的顺序进行排序。和 HashSet 类似,TreeSet 中的元素实际上是存储在 TreeMap 的键中的,而对应的值则是一个固定的 Object 对象。

关键部分源码如下:

public class TreeSet<E> extends AbstractSet<E> implements NavigableSet<E>, Cloneable, java.io.Serializable{
    private static final Object PRESENT = new Object();
    
    public TreeSet() {
        this(new TreeMap<>());
    }
    
    public boolean add(E e) {
        return m.put(e, PRESENT)==null;
    }
}

LinkedHashSet 则是基于 LinkedHashMap 来实现的。它不仅能保证元素的唯一性,还可以记住元素的插入顺序。和其他两种 Set 实现一样,LinkedHashSet 的元素也是存储在 LinkedHashMap 的键中的。

关键部分源码如下:

public class LinkedHashSet<E> extends HashSet<E> implements Set<E>, Cloneable, java.io.Serializable {
    public LinkedHashSet() {
        super(16, .75f, true);
    }
}

public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable{
    HashSet(int initialCapacity, float loadFactor, boolean dummy) {
        map = new LinkedHashMap<>(initialCapacity, loadFactor);
    }
    
    public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }
}

9.总结

下面是一个简单的总结表格:

特性HashMapHashtableLinkedHashMapTreeMapProperties
Key 的顺序无序无序插入顺序(或访问顺序)有序(自然排序、定制排序)无序
允许 null
线程安全
性能较高中等
基于Hash表Hash表Hash表+链表红黑树Hash表
特殊功能记录插入顺序排序存储字符串

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/576771.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深入浅出Docker:Java开发者的快速上手指南

前言1. Docker是什么&#xff1f;2. 安装Docker3. 使用Docker容器运行Java应用4. 使用Docker部署Java Web应用5. 总结 前言 在今天的软件开发环境中&#xff0c;Docker已经成为了一种常见的开发和部署工具。无论你是前端开发者、后端开发者&#xff0c;还是DevOps工程师&#…

【C++系列P3】‘类与对象‘-三部曲——[基础知识](1/3)

前言 大家好吖&#xff0c;欢迎来到 YY 滴 C系列 &#xff0c;热烈欢迎&#xff01; 【 类与对象-三部曲】的大纲主要内容如下&#xff1a; 如标题所示&#xff0c;本章是【 类与对象-三部曲】三章中的第一章节——基础知识章节&#xff0c;主要内容如下&#xff1a; 目录 一.…

Redis(五)发布与订阅

文章目录 1、什么是发布与订阅2、指令与描述3、指令测试 1、什么是发布与订阅 Redis 发布订阅 (pub/sub) 是一种消息通信模式&#xff1a;发送者 (pub) 发送消息&#xff0c;订阅者 (sub) 接收消息。 Redis 的 subscribe 命令可以让客户端订阅任意数量的频道&#xff0c; 每当…

一文带你了解MySQL之事务的简介

前言&#xff1a; 事务&#xff08;Transaction&#xff09;是一组SQL组成的执行单元&#xff08;Unit&#xff09;&#xff0c;是数据库并发控制和恢复回滚的基本单位。一个事务中可能包含多个SQL&#xff0c;要么都失败&#xff0c;要么都成功&#xff0c;今天我们就详细学习…

Linux|shell编程|拷贝大文件之显示进度条

前言&#xff1a; Linux由于自身并不是一个图形化的界面&#xff0c;因此&#xff0c;命令行是它的一个基础交互模式&#xff0c;而我们有的时候需要进度条来让程序运行的更加美观&#xff0c;更加直观&#xff0c;例如&#xff0c;一些比较消耗io的操作&#xff0c;文件拷贝&…

计算机操作系统第四版第八章磁盘存储器的管理—课后习题答案

1.目前常用的外存有哪几种组织方式? (1)连续组织方式。为每一个文件分配--组位置相邻接的盘块&#xff0c;由此形成的文件物理结构是顺序式的文件结构。 (2)链接组织方式。为每个文件分配一组位置离散的盘块&#xff0c;通过给每个盘块设置一个指针,将属于同-一个文件的盘块链…

【SDP协议】

SDP 1.概念2术语2.1 SERVICE ATTRIBUTE2.3 UUID 3 数据表示3.2 hci log4.4.4.3 PARTIAL RESPONSES AND CONTINUATION STATE4.4.4.4 ERROR HANDLING4.4.4.5 SERVICE SEARCH TRANSACTION4.4.4.6 SERVICE ATTRIBUTE TRANSACTION4.4.4.3 SERVICE SEARCH ATTRIBUTE TRANSACTION4.4.4…

【密码学复习】第九讲 密钥管理(二)

公钥的分发问题 广播式公钥分发&#xff1a;任意通信方将它的公钥发送给另一方或广播给其他通信各方。 目录式公钥分发&#xff1a;由可信机构维护一个公开、动态、可访问的公开密钥目录。可以通过可信渠道到可信机构登记并申请增、删、改自己的公钥。其他人可以基于公开…

ARM的七种工作模式

分类 ARM的工作模式分为普通模式、特权模式&#xff0c;其中特权模式又细分为六种模式。 普通模式用户模式&#xff08;User&#xff09;大部分任务执行在这种模式 特权模式快速中断模式FIQ当一个高优先级&#xff08;fast) 中断产生时将会进入这种模式普通中断模式IRQ当一个…

数据库基础——4.select语句

这篇文章我们来讲一下select语句&#xff0c;这是数据库中最最重要的一个关键字 目录 1.select的基本用法 1.1 select的基本用法 1.2 列的别名 1.3 去重查询 1.4 空值参与运算 1.5 着重号 1.6 查询常数 1.7 条件查询 2. 查看表结构 1.select的基本用法 1.1 select的…

12. 测试搭建百万并发项目

本文利用四台虚拟机&#xff0c;实现了百万并发的项目&#xff0c;并解决其中遇到的一些问题 一、百万并发项目 准备4个虚拟机&#xff0c;其中一个4G内存&#xff0c;2核CPU&#xff1b;另外三个2G内存&#xff0c;1核CPU。 在服务器中运行11节的代码&#xff0c;客户端中运…

分享一个500页面给大家

先看效果&#xff1a; 再看代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>500页面</title><style>body,html {padding: 0;margin: 0;font-family: Quicksand, sans-s…

学生端程序(极域电子教室)破解方法

今天信息课上&#xff0c;由于老师的电脑控制&#xff08;极域电子教室&#xff09;导致某些同学无法摸鱼&#xff0c;于是他们就想让我破解&#xff0c;这道不难&#xff0c;我也就使用了三四周就破解出来了&#xff0c;今天就来和大家分享一下极域电子教室的破解方法 目录 …

(四)调整PID控制器参数的指南

一、控制系统设计快速入门和环境 首先确定一下控制任务。快速、精准地控制&#xff0c;必要的稳定性&#xff0c;时域&#xff08;上升时间、超调等&#xff09;&#xff0c;频域&#xff08;带宽、阻尼比&#xff09;然后明白控制系统特点。类积分器&#xff1f;开环稳定性、高…

深度学习实战项目(三)-行人检测重识别yolov5+reid(跑通+界面设计)

行人检测重识别yolov5reid&#xff08;跑通界面设计&#xff09; 参考源代码: github 权重文件&#xff1a; 根据github上面的网盘进行权重下载&#xff1a; 检测&#xff1a;将 ReID_resnet50_ibn_a.pth放在person_search/weights文件下&#xff0c;yolov5s.pt放person_sear…

pytest之fixture

fixture 0、文档1、局部前置处理2、全局前置处理3、全局前置处理 0、文档 pytest-fixture fixture 1、局部前置处理 pytest.fixture() 装饰器用于声明函数是一个fixture&#xff0c;该fixture的名字默认为函数名&#xff0c;也可以自己指定名称&#xff08;name取别名&#…

CBAM: Convolutional Block Attention Module论文总结和代码实现

论文&#xff1a;https://arxiv.org/pdf/1807.06521.pdf 中文版&#xff1a;CBAM: Convolutional Block Attention Module中文翻译 源码&#xff1a;https://github.com/Jongchan/attention-module 目录 一、论文的出发点 二、论文的主要工作 三、CBAM模块的具体实现 四…

【C++系列P5】‘类与对象‘-三部曲——[对象特殊成员](3/3)

前言 大家好吖&#xff0c;欢迎来到 YY 滴 C系列 &#xff0c;热烈欢迎&#xff01; 【 类与对象-三部曲】的大纲主要内容如下&#xff1a; 如标题所示&#xff0c;本章是【 类与对象-三部曲】三章中的第三章节——对象&成员章节&#xff0c;主要内容如下&#xff1a; 目录…

1723_PolySpace Bug Finder命令行执行探索

全部学习汇总&#xff1a; GreyZhang/g_matlab: MATLAB once used to be my daily tool. After many years when I go back and read my old learning notes I felt maybe I still need it in the future. So, start this repo to keep some of my old learning notes servral …

小兔鲜--项目总结3

目录 结算模块-地址切换交互实现 地址切换交互需求分析 打开弹框交互实现 地址激活交互实现 订单模块-生成订单功能实现 支付模块-实现支付功能 支付业务流程 支付模块-支付结果展示 支付模块-封装倒计时函数 理解需求 实现思路分析 会员中心-个人中心信息渲染 分页…