C# 集合框架的主要接口和基类的关系(含源码讲解)

news2024/12/27 0:18:20

目录

集合接口继承关系

基于接口的实现

主要接口

接口的作用

1. IEnumerable

2. IEnumerator

3. ICollection

4. IList

5. IDictionary,>

主要基类

基类的作用

1. Collection

2. List

3. Dictionary,>

4.LinkedList

5.HashSet

6.SortedList,>

7.Queue

8.Stack


在C#中,集合框架的设计遵循了OOP(面向对象编程)的原则,尤其是通过继承和接口的使用,使得不同类型的集合能够共享相同的基本行为和方法。

集合接口继承关系

IEnumerable<T>
    └── ICollection<T>
        └── IList<T>
            └── List<T>

IEnumerable<T>
    └── ICollection<KeyValuePair<TKey, TValue>>
        └── IDictionary<TKey, TValue>
            └── Dictionary<TKey, TValue>

IEnumerable<T>
    └── ISet<T>
        └── HashSet<T>

IEnumerable<T>
    └── IReadOnlyCollection<T>
        └── IReadOnlyList<T>
            └── ReadOnlyCollection<T>

IEnumerable<T>
    └── ICollection<T>
        └── Queue<T>

IEnumerable<T>
    └── ICollection<T>
        └── Stack<T>

IEnumerable<T>
    └── ICollection<T>
        └── Collection<T>
            ├── ObservableCollection<T>
            ├── LinkedList<T>
            └── SortedList<TKey, TValue>

基于接口的实现

集合框架中的基类实现了多个接口,提供具体的功能实现。

例如,List<T> 实现了 IList<T>ICollection<T>IEnumerable<T>。这使得 List<T> 可以通过这些接口进行操作,例如添加、删除和遍历元素。 实现接口的类可以被视为该接口类型。

在编写方法时,可以使用接口作为参数类型,从而实现对不同集合类型的一致操作。

public void PrintElements(IEnumerable<int> collection)
{
    foreach (var item in collection)
    {
        Console.WriteLine(item);
    }
}

主要接口

接口是一种类型,它定义了一系列方法、属性、事件和索引器的签名,但并不提供具体的实现。接口本身不能被实例化,而是通过实现该接口的类或结构来提供实际的功能

接口的作用

  • 行为定义:接口定义了类应遵循的行为契约。实现相同接口的不同类可以表现出不同的行为,但它们都遵循相同的操作标准。
  • 解耦合:通过依赖接口而不是具体实现,开发者可以降低类之间的耦合度,从而提高系统的灵活性和可维护性。
  • 多态性:接口允许不同类的对象以相同的方式进行操作,支持多态设计。例如,IEnumerable<T> 接口使得所有实现了该接口的集合类型都可以使用 foreach 循环进行遍历。

1. IEnumerable<T>

  • 功能:定义了一个用于迭代集合的基本约定。所有实现了 IEnumerable<T> 的集合都可以使用 foreach 循环进行遍历。
  • 基类关系:这是所有集合接口的基础,其他集合接口(如 ICollection<T>IList<T>)都通过它来支持枚举。
public interface IEnumerable<T> {
    IEnumerator<T> GetEnumerator();
}

2. IEnumerator<T>

  • 功能:用于遍历集合的接口,提供对集合元素的访问和管理游标的位置。
  • 基类关系:它是集合中用于支持迭代的关键接口,通常由实现了 IEnumerable<T> 的类返回。
public interface IEnumerator<out T> : IDisposable, IEnumerator
{
    T Current { get; }
}

3. ICollection<T>

  • 功能:扩展了 IEnumerable<T>,增加了对集合元素计数、添加、删除等功能的支持。
  • 基类关系:它是 IEnumerable<T> 的子接口,也是 IList<T>ISet<T> 的基础,提供对集合的基本操作。
public interface ICollection<T> : IEnumerable<T> {
    int Count { get; }
    bool IsReadOnly { get; }
    void Add(T item);
    void Clear();
    bool Contains(T item);
    void CopyTo(T[] array, int arrayIndex);
    bool Remove(T item);
}

4. IList<T>

  • 功能:表示一个可索引的集合,允许通过整数索引访问元素,并提供插入和删除操作。
  • 基类关系:继承自 ICollection<T>,添加了索引访问的功能。
public interface IList<T> : ICollection<T>, IEnumerable<T>
{
    T this[int index] { get; set; }
    int IndexOf(T item);
    void Insert(int index, T item);
    void RemoveAt(int index);
}

5. IDictionary<TKey, TValue>

  • 功能:表示一个键值对集合,允许通过键快速访问值。
  • 基类关系:实现了 ICollection<KeyValuePair<TKey, TValue>> 接口,并用于方便地管理键值对。
public interface IDictionary<TKey, TValue> : ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>
{
    TValue this[TKey key] { get; set; }
    ICollection<TKey> Keys { get; }
    ICollection<TValue> Values { get; }
    void Add(TKey key, TValue value);
    bool ContainsKey(TKey key);
    bool Remove(TKey key);
    bool TryGetValue(TKey key, out TValue value);
}

主要基类

基类是一个具体的类,它可以包含实现、字段、属性和方法。基类可以被其他类继承,从而允许子类重用其实现,并可以扩展或重写这些方法。

基类的作用

  • 代码重用:基类提供了一种机制,可以在类层次结构中共享通用功能,减少代码重复。例如,Collection<T> 类实现了基础的集合操作,用于所有其他集合的基础。
  • 状态管理:基类可以定义字段,提供共享的状态(数据)管理,使得子类可以继承并使用这些状态。
  • 方法重写:基类可以定义虚方法或抽象方法,允许子类根据需要重写或实现这些方法,以便提供特定的行为。

1. Collection<T>

  • 功能:提供了基本的集合操作,允许子类扩展和实现集合行为。
  • 接口关系:实现了 ICollection<T>IEnumerable<T> 接口,作为其他集合类的基础。
// 泛型集合基类,提供基本的集合操作
public class Collection<T> : ICollection<T>, IEnumerable<T>, IEnumerable
{
    // 内部使用的列表存储实际的元素
    private readonly List<T> _items = new List<T>();

    // 获取集合中元素的数量
    public int Count => _items.Count;

    // 判断集合是否是只读的,这里返回 false 表示可以修改
    public bool IsReadOnly => false;

    // 向集合添加元素的方法
    public void Add(T item)
    {
        _items.Add(item);
        // 触发集合更改的通知,通常用于 ObservableCollection 中
    }

    // 清空集合中的所有元素
    public void Clear()
    {
        _items.Clear();
        // 触发集合更改的通知
    }

    // 检查集合中是否包含指定的元素
    public bool Contains(T item)
    {
        return _items.Contains(item);
    }

    // 将集合中的元素复制到指定数组中
    public void CopyTo(T[] array, int arrayIndex)
    {
        _items.CopyTo(array, arrayIndex);
    }

    // 返回用于迭代集合的枚举器
    public IEnumerator<T> GetEnumerator()
    {
        return _items.GetEnumerator();
    }

    // 封装 IEnumerable 接口的未泛型版本
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    // 索引器,允许通过索引访问集合中的元素
    public T this[int index]
    {
        get => _items[index]; // 返回指定索引的元素
        set
        {
            _items[index] = value; // 设置指定索引的元素
            // 触发集合更改的通知
        }
    }
}
  • 字段_items 是基础的存储容器,通常使用 List<T> 来实现内部存储。
  • Count 属性:返回集合中元素的数量。
  • Add 方法:添加新元素到集合,并可以触发更改通知(通常在 ObservableCollection<T> 中使用)。
  • GetEnumerator 方法:实现了 IEnumerable<T> 接口,允许使用 foreach 循环遍历集合。
  • 索引器:通过索引访问集合中的元素,支持 this[int index]

2. List<T>

  • 功能:提供动态数组的实现,支持按索引访问和其他常用集合操作。
  • 接口关系:继承自 Collection<T>,实现了 IList<T>IEnumerable<T>,因此可以使用集合的基础操作。
// 泛型动态数组集合,支持索引访问
public class List<T> : IList<T>, ICollection<T>, IEnumerable<T>, IEnumerable, IReadOnlyList<T>
{
    // 存储元素的数组
    private T[] _items;
    // 当前元素的数量
    private int _size;
    // 版本号,用于跟踪集合的更改
    private int _version;

    // 默认构造函数,初始化为一个空数组
    public List()
    {
        _items = Array.Empty<T>();
    }

    // 向集合添加新元素的方法
    public void Add(T item)
    {
        // 检查数组是否已满,若满则扩展容量
        if (_size == _items.Length)
        {
            EnsureCapacity(_size + 1);
        }
        _items[_size++] = item; // 将新元素添加到数组
        _version++; // 增加版本号
    }

    // 获取或设置集合的容量
    public int Capacity
    {
        get => _items.Length; // 返回当前容量
        set
        {
            // 如果新容量小于当前元素数量,抛出异常
            if (value < _size) throw new ArgumentOutOfRangeException();
            if (value != _items.Length)
            {
                if (value > 0)
                {
                    // 创建新的数组并复制原数组的元素
                    var newItems = new T[value];
                    if (_size > 0)
                    {
                        Array.Copy(_items, newItems, _size);
                    }
                    _items = newItems; // 更新内部存储数组
                }
                else // 若容量为 0,则清空数组
                {
                    _items = Array.Empty<T>();
                }
            }
        }
    }

    // 返回当前元素数量
    public int Count => _size;

    // 索引器,允许通过索引访问和修改元素
    public T this[int index]
    {
        get => _items[index]; // 获取指定索引的元素
        set => _items[index] = value; // 设置指定索引的元素
    }

    // 确保数组具有足够的容量
    private void EnsureCapacity(int min)
    {
        // 如果当前容量不足,则进行扩展
        if (_items.Length < min)
        {
            int newCapacity = _items.Length == 0 ? 4 : _items.Length * 2; // 计算新容量
            if (newCapacity < min) newCapacity = min; // 确保新容量不小于所需容量
            Capacity = newCapacity; // 设置新容量
        }
    }

    // 其他方法略...
}
  • 字段_items 是实际存储元素的数组,_size 是当前元素数量,_version 用于跟踪集合的变化,支持集合的并发操作。
  • Add 方法:添加元素时首先检查当前容量,如果数组已满,则通过 EnsureCapacity 方法扩展容量。
  • Capacity 属性:用于获取或设置集合的容量,确保集合能容纳更多元素。
  • 索引器:支持通过索引访问和设置元素。

3. Dictionary<TKey, TValue>

  • 功能:基于哈希表的实现,用于存储和快速查找键值对。
  • 接口关系:实现了 IDictionary<TKey, TValue> 接口,并继承ICollection<KeyValuePair<TKey, TValue>>,提供对键值对的管理。
// 泛型字典实现,基于哈希表,用于存储键值对
public class Dictionary<TKey, TValue> : IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable
{
    // 哈希桶,存储每个键的索引
    private int[] _buckets;
    // 存储实际键值对的数组
    private Entry[] _entries;
    // 当前元素的数量
    private int _count;

    // 定义字典中每个元素的结构
    private struct Entry
    {
        public int hashCode; // 哈希值
        public int next; // 指向下一个条目的索引
        public TKey key; // 键
        public TValue value; // 值
    }

    // 默认构造函数,初始化哈希桶和条目数组
    public Dictionary()
    {
        // 初始化逻辑,例如设置初始容量
    }

    // 添加键值对到字典
    public void Add(TKey key, TValue value)
    {
        // 插入逻辑,包括处理冲突
    }

    // 根据键获取值
    public bool TryGetValue(TKey key, out TValue value)
    {
        // 查找逻辑,根据键计算哈希并定位到对应的值
    }

    // 从字典中删除特定的键值对
    public bool Remove(TKey key)
    {
        // 删除逻辑,更新哈希桶
    }

    // 索引器,用于访问和设置字典中的值
    public TValue this[TKey key]
    {
        get
        {
            if (!TryGetValue(key, out TValue value))
            {
                throw new KeyNotFoundException(); // 如果未找到键,抛出异常
            }
            return value; // 返回找到的值
        }
        set => Add(key, value); // 设置值时调用添加方法
    }

    // 其他方法略...
}

4.LinkedList<T>

  • 功能:表示一个双向链表,支持在任意位置快速插入和删除元素。
  • 接口关系:没有直接的接口实现,但可用于构建其他集合类型,如 Queue<T>Stack<T>
public class LinkedList<T>
{
    private LinkedListNode<T> _first; // 链表的第一个节点
    private LinkedListNode<T> _last;  // 链表的最后一个节点

    public LinkedList() { }

    // 添加新节点到链表的末尾
    public void AddLast(T value)
    {
        var newNode = new LinkedListNode<T>(value);
        if (_last == null)
        {
            _first = newNode; // 如果链表为空,设置头尾节点
            _last = newNode;
        }
        else
        {
            _last.Next = newNode; // 设置上一个节点的 Next 指针
            newNode.Previous = _last; // 设置新节点的 Previous 指针
            _last = newNode; // 更新最后一个节点
        }
    }

    // 删除指定节点
    public bool Remove(LinkedListNode<T> node)
    {
        if (node == null) return false; // 检查节点有效性
        if (node.Previous != null)
        {
            node.Previous.Next = node.Next; // 更新前驱节点的 Next 指针
        }
        if (node.Next != null)
        {
            node.Next.Previous = node.Previous; // 更新后继节点的 Previous 指针
        }

        // 更新头尾节点
        if (node == _first) _first = node.Next;
        if (node == _last) _last = node.Previous;

        return true; // 返回删除成功
    }
}

public class LinkedListNode<T>
{
    public T Value { get; set; } // 节点存储的值
    public LinkedListNode<T> Next { get; set; } // 指向下一个节点
    public LinkedListNode<T> Previous { get; set; } // 指向前一个节点

    public LinkedListNode(T value)
    {
        Value = value; // 构造函数,初始化值
    }
}

5.HashSet<T>

  • 功能:提供不允许重复元素的集合,使用哈希表实现,支持集合运算。
  • 接口关系:实现了 ISet<T> 接口,继承自 ICollection<T>,提供基本集合操作。
public class HashSet<T>
{
    private Dictionary<T, bool> _dictionary; // 使用字典存储元素

    public HashSet()
    {
        _dictionary = new Dictionary<T, bool>(); // 初始化字典
    }

    // 添加元素
    public bool Add(T item)
    {
        if (_dictionary.ContainsKey(item))
            return false; // 如果元素已经存在,返回 false
        _dictionary[item] = true; // 添加元素,值设置为 true
        return true; // 返回 true 表示添加成功
    }

    // 删除元素
    public bool Remove(T item)
    {
        return _dictionary.Remove(item); // 使用字典的 Remove 方法
    }

    // 检查集合是否包含指定元素
    public bool Contains(T item)
    {
        return _dictionary.ContainsKey(item); // 使用字典的 ContainsKey 方法
    }
}

6.SortedList<TKey, TValue>

  • 功能:提供基于键的排序的集合,使用键/值对的形式保存数据,支持通过键进行快速查找。
  • 接口关系:实现了 IDictionary<TKey, TValue> 接口,用于定义键值对的集合。
public class SortedList<TKey, TValue>
{
    private List<TKey> _keys; // 存储键的列表
    private List<TValue> _values; // 存储值的列表

    public SortedList()
    {
        _keys = new List<TKey>();
        _values = new List<TValue>();
    }

    // 添加键值对,保持键的有序性
    public void Add(TKey key, TValue value)
    {
        int index = _keys.BinarySearch(key); // 查找插入位置
        if (index < 0) index = ~index; // 索引为负表示未找到,取反得到插入位置
        _keys.Insert(index, key);
        _values.Insert(index, value); // 在相同位置插入值
    }

    // 通过键获取值
    public TValue this[TKey key]
    {
        get
        {
            int index = _keys.IndexOf(key);
            if (index < 0) throw new KeyNotFoundException(); // 找不到键抛出异常
            return _values[index]; // 返回对应的值
        }
    }
}

7.Queue<T>

  • 功能:表示先进先出(FIFO)的集合,适合在需要排队处理的场景下使用。
  • 接口关系:通过使用 LinkedList<T> 作为内部数据结构,支持接口 IEnumerable<T>
public class Queue<T>
{
    private LinkedList<T> _list; // 使用链表存储元素

    public Queue()
    {
        _list = new LinkedList<T>(); // 初始化链表
    }

    // 添加元素到队列末尾
    public void Enqueue(T item)
    {
        _list.AddLast(item); // 调用链表的添加方法
    }

    // 从队列头部移除并返回元素
    public T Dequeue()
    {
        if (_list.Count == 0) throw new InvalidOperationException("Queue is empty.");
        var value = _list.First.Value; // 获取头部元素
        _list.Remove(_list.First); // 从链表中移除头部元素
        return value; // 返回头部元素
    }
}

8.Stack<T>

  • 功能:表示后进先出(LIFO)的集合,使用栈结构来存储元素。
  • 接口关系:同样使用 LinkedList<T> 作为内部结构,支持迭代。
public class Stack<T>
{
    private LinkedList<T> _list; // 使用链表存储元素

    public Stack()
    {
        _list = new LinkedList<T>(); // 初始化链表
    }

    // 将元素推入栈中
    public void Push(T item)
    {
        _list.AddLast(item); // 调用链表的添加方法
    }

    // 从栈中弹出元素
    public T Pop()
    {
        if (_list.Count == 0) throw new InvalidOperationException("Stack is empty.");
        var value = _list.Last.Value; // 获取栈顶元素
        _list.Remove(_list.Last); // 从链表中移除栈顶元素
        return value; // 返回栈顶元素
    }
}

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

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

相关文章

逆向攻防世界CTF系列42-reverse_re3

逆向攻防世界CTF系列42-reverse_re3 参考&#xff1a;CTF-reverse-reverse_re3&#xff08;全网最详细wp&#xff0c;超4000字有效解析&#xff09;_ctfreverse题目-CSDN博客 64位无壳 _int64 __fastcall main(__int64 a1, char **a2, char **a3) {int v4; // [rsp4h] [rbp-…

【韩顺平老师Java反射笔记】

反射 文章目录 基本使用反射机制java程序在计算机有三个阶段反射相关的主要类 反射调用优化Class类的常用方法获取Class对象的6种方式哪些类型有Class对象类加载类加载时机类加载过程图 通过反射获取类的结构信息第一组&#xff1a;java.lang.Class类第二组&#xff1a;java.la…

【热门主题】000075 探索嵌入式硬件设计的奥秘

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 【热…

Swift实现高效链表排序:一步步解读

文章目录 前言摘要问题描述题解解题思路Swift 实现代码代码分析示例测试与结果 时间复杂度空间复杂度总结关于我们 前言 本题由于没有合适答案为以往遗留问题&#xff0c;最近有时间将以往遗留问题一一完善。 148. 排序链表 不积跬步&#xff0c;无以至千里&#xff1b;不积小流…

mysql系列2—InnoDB数据存储方式

背景 本文将深入探讨InnoDB的底层存储机制&#xff0c;包括行格式、页结构、页目录以及表空间等核心概念。通过全面了解这些基础概念&#xff0c;有助于把握MySQL的存储架构&#xff0c;也为后续深入讨论MySQL的索引原理和查询优化策略奠定了基础。 1.行格式 mysql中数据以行…

vue实现echarts饼图自动轮播

echarts官网&#xff1a;Examples - Apache ECharts echartsFn.ts 把echarts函数封装成一个文件 import * as echarts from "echarts";const seriesData [{"value": 12,"name": "过流报警"},{"value": 102,"name&qu…

【Python数据分析五十个小案例】使用自然语言处理(NLP)技术分析 Twitter 情感

博客主页&#xff1a;小馒头学python 本文专栏: Python爬虫五十个小案例 专栏简介&#xff1a;分享五十个Python爬虫小案例 项目简介 什么是情感分析 情感分析&#xff08;Sentiment Analysis&#xff09;是文本分析的一部分&#xff0c;旨在识别文本中传递的情感信息&…

网络安全防护指南:筑牢网络安全防线(5/10)

一、网络安全的基本概念 &#xff08;一&#xff09;网络的定义 网络是指由计算机或者其他信息终端及相关设备组成的按照一定的规则和程序对信息收集、存储、传输、交换、处理的系统。在当今数字化时代&#xff0c;网络已经成为人们生活和工作中不可或缺的一部分。它连接了世…

宏海科技募资额有所缩减,最大销售和采购都重度依赖美的集团

《港湾商业观察》施子夫 11月29日&#xff0c;北交所上市审核委员会将召开2024年第24次上市委审议会议&#xff0c;届时将审议武汉宏海科技股份有限公司&#xff08;以下简称&#xff0c;宏海科技&#xff09;的首发上会事项。 在上会之前&#xff0c;宏海科技共收到北交所下…

算法日记 36-38day 动态规划

今天把动态规划结束掉&#xff0c;包括子序列以及编辑距离 题目&#xff1a;最长公共子序列 1143. 最长公共子序列 - 力扣&#xff08;LeetCode&#xff09; 给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 &…

Gopeed 1.6.3 | 不限速下载工具附百度网盘不限速教程

Gopeed是一款高效且易于使用的下载软件。它具有加速下载速度的功能&#xff0c;可以帮助用户更快地下载文件。此外&#xff0c;Gopeed还支持多线程下载&#xff0c;可以同时下载多个文件&#xff0c;提高下载效率。它提供了简洁的界面和简单的操作&#xff0c;方便用户操作和管…

K8S版本和istio版本的对照关系

版本对照关系 下载地址1 下载地址2

【大数据学习 | Spark-SQL】关于RDD、DataFrame、Dataset对象

1. 概念&#xff1a; RDD&#xff1a; 弹性分布式数据集&#xff1b; DataFrame&#xff1a; DataFrame是一种以RDD为基础的分布式数据集&#xff0c;类似于传统数据库中的二维表格。带有schema元信息&#xff0c;即DataFrame所表示的二维表数据集的每一列都带有名称和类型…

如何调用百度文心一言API实现智能问答

诸神缄默不语-个人CSDN博文目录 百度需要先认证个人信息才能使用LLM API。 文章目录 1. 获得 API Key2. 撰写代码并实现提问和回答2.1 用openai包实现调用2.2 用openai包实现流式调用2.3 用openai包实现工具调用2.4 构建智能体2.5 文生图2.6 图生图 3. 用gradio建立大模型问答…

python除了熟悉的pandas,openpyxl库也很方便的支持编辑Excel表

excel表格是大家经常用到的文件格式&#xff0c;各行各业都会跟它打交道。之前文章我们介绍了使用openpyxl和xlrd库读取excel表数据&#xff0c;使用xlwt库创建和编辑excel表&#xff0c;在办公自动化方面可以方便我们快速处理数据&#xff0c;帮助我们提升效率。 python之open…

JMeter 并发策略-针对准点秒杀场景的压测实现

一、场景的压测实现 1&#xff0c;创建线程组&#xff0c;10并发用户执行5次&#xff1b; 2&#xff0c;创建 Synchronizing Timer 元件,用于同步线程&#xff0c;设置同步元件 Synchronizing Timer 3&#xff0c;创建 http 请求4&#xff0c;创建 view results in table 元件…

损失函数分类

1. NLLLoss&#xff08;负对数似然损失&#xff09; 定义&#xff1a; 直接对预测的概率 p(yi) 的负对数求平均。通常配合 Softmax 使用&#xff0c;输入为对数概率。 优点&#xff1a; 对离散分类问题效果良好。更灵活&#xff0c;用户可以自行计算 Softmax。 缺点&#x…

【热门主题】000072 分布式数据库:开启数据管理新纪元

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 【热…

算法笔记:力扣148. 排序链表

思路&#xff1a; 将链表中的节点一一取出放到list集合中&#xff0c;然后通过Comparator实现排序&#xff0c;对排序好的list节点一一取出&#xff0c;组成排序好的新链表。 关键思路&#xff1a; Comparator实现对ListNode的排序&#xff1b; &#x1f4a1;注意&#xff…

Kafka知识体系

一、认识Kafka 1. kafka适用场景 消息系统&#xff1a;kafka不仅具备传统的系统解耦、流量削峰、缓冲、异步通信、可扩展性、可恢复性等功能&#xff0c;还有其他消息系统难以实现的消息顺序消费及消息回溯功能。 存储系统&#xff1a;kafka把消息持久化到磁盘上&#xff0c…