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

python字典和集合——笔记

一、介绍
1、泛映射类型
collections.abc模块中有Mapping和MutableMapping这两个抽象基类,它们的作用是为dict和其他类似的类型定义形式接口(在Python 2.6到Python 3.2的版本中,这些类还不属于collections.abc模块,而是隶属于collections模块)。
在这里插入图片描述
然而,非抽象映射类型一般不会直接继承这些抽象基类,它们会直接对dict或是collections.UserDict进行扩展。
这些抽象基类的主要作用是作为形式化的文档,它们定义了构建一个映射类型所需要的最基本的接口。然后它们还可以跟isinstance一起被用来判定某个数据是不是广义上的映射类型。

isinstance(my_dict, abc.Mapping)
Out[138]: True

标准库里的所有映射类型都是利用dict来实现的,因此它们有个共同的限制,即只有可散列的数据类型才能用作这些映射里的键。

1.1如果一个对象是可散列的,那么在这个对象的生命周期中,它的散列值是不变的,而且这个对象需要实现__hash__( )方法。另外可散列对象还要有__eq__( )方法,这样才能跟其他键做比较。如果两个可散列对象是相等的,那么它们的散列值一定是一样的……
原子不可变数据类型(str、bytes和数值类型)都是可散列类型,frozenset也是可散列的,因为根据其定义,frozenset里只能容纳可散列类型。元组的话,只有当一个元组包含的所有元素都是可散列类型的情况下,它才是可散列的。

tt=(1,2,[30,40])
t1=(1,2,(30,40))
hash(tt)
TypeError: unhashable type: 'list'
hash(t1)
Out[142]: -3907003130834322577

1.2 创建字典的不同方式

a = dict(one=1, two=2, three=3)
b = {'one':1,'two':2, 'three':3}
c = dict(zip(['one', 'two', 'three'], [1,2,3]))
d = dict([('two', 2), ('one', 1), ('three',3)])
e = dict({'three':3, 'one':1, 'two':2})
a==b==c==d==e
Out[148]: True

2、字典推导
字典推导(dictcomp)可以从任何以键值对作为元素的可迭代对象中构建出字典。下面就展示了利用字典推导可以把一个装满元组的列表变成了字典。

country = ['China', 'Brazil', 'Russia', 'Japan']
country_code={co:len(co) for co in country}
country_code
Out[154]: {'China': 5, 'Brazil': 6, 'Russia': 6, 'Japan': 5}

3、映射类型的常见方法

# 返回国家对应的值,没有的话返回-1
country_code.get('China',-1)
Out[155]: 5
country_code.get('USA',-1)
Out[156]: -1
# 返回country_code中的所有键值对
country_code.items()
Out[157]: dict_items([('China', 5), ('Brazil', 6), ('Russia', 6), ('Japan', 5)])
# 随机返回一个键值对,并从字典中移除它
country_code.popitem()
Out[158]: ('Japan', 5)
country_code
Out[159]: {'China': 5, 'Brazil': 6, 'Russia': 6}
# 返回brazil所对应的值,并删除这个键值对。 如果没有,则返回默认值
country_code.pop('Brazil')
Out[160]: 6
country_code.pop('Brazil',-1)
Out[161]: -1
country_code
Out[162]: {'China': 5, 'Russia': 6}

OrderedDict.popitem()会移除字典里最先插入的元素(先进先出);同时这个方法还有一个可选的last参数,若为真,则会移除最后插入的元素(后进先出)

4、映射的弹性键查询
有时候为了方便起见,就算某个键在映射里不存在,我们也希望在通过这个键读取值的时候能得到一个默认值。有两个途径能帮我们达到这个目的。

  • 一个是通过defaultdict这个类型而不是普通的dict
  • 另一个是给自己定义一个dict的子类,然后在子类中实现__missing__方法。
    4.1 defaultdict:处理找不到的键的一个选择
    在实例化一个defaultdict的时候,需要给构造方法提供一个可调用对象,这个可调用对象会在__getitem__碰到找不到的键的时候被调用,让__getitem__返回某种默认值。
    比如,我们新建了这样一个字典:dd=defaultdict(list),如果键’new-key’在dd中还不存在的话,表达式dd[‘new-key’]会按照以下的步骤来行事。
    (1)调用list( )来建立一个新列表。
    (2)把这个新列表作为值,'new-key’作为它的键,放到dd中。
    (3)返回这个列表的引用。
    而这个用来生成默认值的可调用对象存放在名为default_factory的实例属性里。
import collections
names = collections.defaultdict(list)
names['1班'].append('李明')
names
Out[166]: defaultdict(list, {'1班': ['李明']})names.get('2班').append('李明')
Traceback (most recent call last):
AttributeError: 'NoneType' object has no attribute 'append'

defaultdict里的default_factory只会在__getitem__里被调用,在其他的方法里完全不会发挥作用。比如,dd是个defaultdict,k是个找不到的键, dd[k]这个表达式会调用default_factory创造某个默认值,而dd.get(k)则会返回None。

所有这一切背后的功臣其实是特殊方法__missing__。它会在defaultdict遇到找不到的键的时候调用default_factory,而实际上这个特性是所有映射类型都可以选择去支持的
4.2 特殊方法__missing__
所有的映射类型在处理找不到的键的时候,都会牵扯到__missing__方法。这也是这个方法称作“missing”的原因。虽然基类dict并没有定义这个方法,但是dict是知道有这么个东西存在的。也就是说,如果有一个类继承了dict,然后这个继承类提供了__missing__方法,那么在__getitem__碰到找不到的键的时候,Python就会自动调用它,而不是抛出一个KeyError异常。
missing__方法只会被__getitem__调用(比如在表达式d[k]中)。提供__missing__方法对get或者__contains_(in运算符会用到这个方法)这些方法的使用没有影响。这也是我在上一节最后的警告中提到,defaultdict中的default_factory只对__getitem__有作用的原因。

示例 StrKeyDict0在查询的时候把非字符串的键转换为字符串

class StrKeyDict0(dict):def __missing__(self, key):if isinstance(key, str):raise KeyError(key)return self[str(key)]def get(self, key, default=None):try:return self[key]except KeyError:return default
d = StrKeyDict0([('2', 'two'),('4', 'four')])
d['2']
Out[170]: 'two'
d[4]
Out[171]: 'four'
d[1]
Traceback (most recent call last):
KeyError: '1'
d.get('2')
Out[173]: 'two'
d.get(4)
Out[174]: 'four'
d.get(1, 'N/A')
Out[175]: 'N/A'

5、字典的变种
这一节总结了标准库里collections模块中,除了defaultdict之外的不同映射类型。
5.1 collections.OrderedDict:这个类型在添加键的时候会保持顺序,因此键的迭代次序总是一致的。OrderedDict的popitem方法默认删除并返回的是字典里的最后一个元素,但是如果像my_odict.popitem(last=False)这样调用它,那么它删除并返回第一个被添加进去的元素。
5.2 collections.ChainMap:该类型可以容纳数个不同的映射对象,然后在进行键查找操作的时候,这些对象会被当作一个整体被逐个查找,直到键被找到为止。这个功能在给有嵌套作用域的语言做解释器的时候很有用,可以用一个映射对象来代表一个作用域的上下文。在collections文档介绍ChainMap对象的那一部分里有一些具体的使用示例,其中包含了下面这个Python变量查询规则的代码片段:

import collections
chain_map = collections.ChainMap({'a':1, 'b':2},{'c':3},{'d':4})
all_dict = dict(chain_map)
all_dict
Out[5]: {'d': 4, 'c': 3, 'a': 1, 'b': 2}

5.3 Counter:这个映射类型会给键准备一个整数计数器。每次更新一个键的时候都会增加这个计数器。所以这个类型可以用来给可散列表对象计数,或者是当成多重集来用——多重集合就是集合里的元素可以出现不止一次。Counter实现了+和-运算符用来合并记录,还有像most_common([n])这类很有用的方法。

ct = collections.Counter('ababdadfawwwwweijisafl')
ct
Out[7]: Counter({'a': 5, 'b': 2,'d': 2,'f': 2,'w': 5,'e': 1, 'i': 2,'j': 1,'s': 1, 'l': 1})
ct.update('ddddddeeeeeee')
ct
Out[9]: Counter({'a': 5, 'b': 2, 'd': 8, 'f': 2, 'w': 5,'e': 8,'i': 2,'j': 1,'s': 1,'l': 1})
ct.most_common(3)
Out[10]: [('d', 8), ('e', 8), ('a', 5)]

5.4 collections.UserDict:就创造自定义映射类型来说,以UserDict为基类,总比以普通的dict为基类要来得方便。

import collections
class StrKeyDict(collections.UserDict):def __missing__(self, key):if isinstance(key,str):raise KeyError(key)return self[str(key)]def __contains__(self, key):return str(key) in self.datadef __setitem__(self, key, item):self.data[str(key)] = item

因为UserDict继承的是MutableMapping,所以StrKeyDict里剩下的那些映射类型的方法都是从UserDict、MutableMapping和Mapping这些超类继承而来的。特别是最后的Mapping类,它虽然是一个抽象基类(ABC),但它却提供了好几个实用的方法。以下两个方法值得关注。

  • MutableMapping.update:这个方法不但可以为我们所直接利用,它还用在__init__里,让构造方法可以利用传入的各种参数(其他映射类型、元素是(key, value)对的可迭代对象和键值参数)来新建实例。因为这个方法在背后是用self[key]=value来添加新值的,所以它其实是在使用我们的__setitem__方法。
  • Mapping.get:在StrKeyDict0中,我们不得不改写get方法,好让它的表现跟__getitem__一致。而在示例3-8中就没这个必要了,因为它继承了Mapping.get方法,

6、不可变映射类型
标准库里所有的映射类型都是可变的,但有时候你会有这样的需求,比如不能让用户错误地修改某个映射。从Python 3.3开始,types模块中引入了一个封装类名叫MappingProxyType。如果给这个类一个映射,它会返回一个只读的映射视图。虽然是个只读视图,但是它是动态的。这意味着如果对原映射做出了改动,我们通过这个视图可以观察到,但是无法通过这个视图对原映射做出修改。

from types import MappingProxyType
d = {1:'A'}
d_proxy = MappingProxyType(d)
d_proxy
Out[12]: mappingproxy({1: 'A'})
d_proxy[1]
Out[13]: 'A'
d_proxy[2] = 'b'
Traceback (most recent call last):
TypeError: 'mappingproxy' object does not support item assignment
d[2] = 'c'
d_proxy
Out[16]: mappingproxy({1: 'A', 2: 'c'})

7、集合论
集合的本质是许多唯一对象的聚集。因此,集合可以用于去重

l = ['spam', 'spam', 'eggs', 'spam']
set(l)
Out[18]: {'eggs', 'spam'}
list(set(l))
Out[19]: ['spam', 'eggs']

除了保证唯一性,集合还实现了很多基础的中缀运算符。给定两个集合a和b,a | b返回的是它们的合集,a & b得到的是交集,而a-b得到的是差集。

7.1 集合字面量
除空集之外,集合的字面量——{1}、{1, 2},等等——看起来跟它的数学形式一模一样。如果是空集,那么必须写成set( )的形式。
7.2 集合操作
集合的数学运算:这些方法或者会生成新集合,或者会在条件允许的情况下就地修改集合。

# 定义集合
a = {1, 2, 3, 4, 5, 6}
b = {4,5,6,7,8,9,20}
# 求交集操作
a.__and__(b)
Out[25]: {4, 5, 6}
a&b
Out[26]: {4, 5, 6}
# 把a更新为a与b的交集
a.__iand__(b)
Out[28]: {4, 5, 6}
a
Out[29]: {4, 5, 6}
a &= b
Out[30]: {4, 5, 6}
# a和b的并集
a|b
Out[30]: {4, 5, 6, 7, 8, 9, 20}
a.__or__(b)
Out[32]: {4, 5, 6, 7, 8, 9, 20}
# 把a更新为a和b的并集
a.__ior__(b)
Out[33]: {4, 5, 6, 7, 8, 9, 20}
a
Out[34]: {4, 5, 6, 7, 8, 9, 20}
# 求a和b的差集
a -b
Out[37]: set()
a.__sub__(b)
Out[38]: set()
# 把a更新为a和b的差集
a -= b
a
Out[40]: set()

8、set和dict的背后
8.1 字典中的散列表
散列表其实是一个稀疏数组(总是有空白元素的数组称为稀疏数组)。
因为Python会设法保证大概还有三分之一的表元是空的,所以在快要达到这个阈值的时候,原有的散列表会被复制到一个更大的空间里面。如果要把一个对象放入散列表,那么首先要计算这个元素键的散列值。Python中可以用hash( )方法来做这件事情,接下来会介绍这一点。

  • 内置的hash( )方法可以用于所有的内置类型对象。如果是自定义对象调用hash( )的话,实际上运行的是自定义的__hash__。如果两个对象在比较的时候是相等的,那它们的散列值必须相等,否则散列表就不能正常运行了。例如,如果1==1.0为真,那么hash(1)==hash(1.0)也必须为真,但其实这两个数字(整型和浮点)的内部结构是完全不一样的。
  • 如果search_key和found_key不匹配的话,这种情况称为散列冲突。发生这种情况是因为,散列表所做的其实是把随机的元素映射到只有几位的数字上,而散列表本身的索引又只依赖于这个数字的一部分。为了解决散列冲突,算法会在散列值中另外再取几位,然后用特殊的方法处理一下,把新得到的数字再当作索引来寻找表元。[插图]若这次找到的表元是空的,则同样抛出KeyError;若非空,或者键匹配,则返回这个值;或者又发现了散列冲突,则重复以上的步骤。
    8.2 dict的实现及其导致的结果
    8.2.1 下面的内容会讨论使用散列表给dict带来的优势和限制都有哪些。
  • 键必须是可散列的: 一个可散列的对象必须满足以下要求。(1)支持hash( )函数,并且通过__hash__( )方法所得到的散列值是不变的。(2)支持通过__eq__( )方法来检测相等性。(3)若a==b为真,则hash(a)hash(b)也为真。所有由用户自定义的对象默认都是可散列的,因为它们的散列值由id( )来获取,而且它们都是不相等的。
    **如果你实现了一个类的__eq__方法,并且希望它是可散列的,那么它一定要有个恰当的__hash__方法,保证在a
    b为真的情况下hash(a)==hash(b)也必定为真。否则就会破坏恒定的散列表算法,导致由这些对象所组成的字典和集合完全失去可靠性,这个后果是非常可怕的。另一方面,如果一个含有自定义的__eq__依赖的类处于可变的状态,那就不要在这个类中实现__hash__方法,因为它的实例是不可散列的**
  • 字典在内存上的开销巨大:由于字典使用了散列表,而散列表又必须是稀疏的,这导致它在空间上的效率低下。
  • 键查询很快:dict的实现是典型的空间换时间:字典类型有着巨大的内存开销,但它们提供了无视数据量大小的快速访问——只要字典能被装在内存里。
  • 键的次序取决于添加顺序:当往dict里添加新键而又发生散列冲突的时候,新键可能会被安排存放到另一个位置。于是下面这种情况就会发生:由dict([(key1, value1), (key2,value2)])和dict([(key2,value2), (key1, value1)])得到的两个字典,在进行比较的时候,它们是相等的;但是如果在key1和key2被添加到字典里的过程中有冲突发生的话,这两个键出现在字典里的顺序是不一样的。
    8.3 set的实现以及导致的结果
    set和frozenset的实现也依赖散列表,但在它们的散列表里存放的只有元素的引用(就像在字典里只存放键而没有相应的值)。在set加入到Python之前,我们都是把字典加上无意义的值当作集合来用的。
  • 集合里的元素必须是可散列的
  • 集合很消耗内存。
  • 可以很高效地判断元素是否存在于某个集合。
  • 元素的次序取决于被添加到集合里的次序。
  • 往集合里添加元素,可能会改变集合里已有元素的次序。

相关文章:

python字典和集合——笔记

一、介绍 1、泛映射类型 collections.abc模块中有Mapping和MutableMapping这两个抽象基类,它们的作用是为dict和其他类似的类型定义形式接口(在Python 2.6到Python 3.2的版本中,这些类还不属于collections.abc模块,而是隶属于coll…...

TEX:显示文本

文章目录字体选择字体fontspec宏包根据字体形状控制字体为不同的字体形状选择不同的特征为不同的字体大小状选择不同的特征中文字体选择xeCJK宏包字体选择与设置XELATEX字体名查找字体集与符号居中与缩进居中单边调整两边缩进诗歌缩进列表itemize样例enumerate样例description样…...

SS-ELM-AE与S2-BLS相关论文阅读记录

Broad learning system for semi-supervised learning 摘要:本文认为,原始BLS采用的稀疏自编码器来生成特征节点是一种无监督学习方法,这意味着忽略了标注数据的一些信息,并且难以保证同类样本之间的相似性和相邻性,同…...

ESP32设备驱动-MAX6675冷端补偿K热电偶数字转换器

MAX6675冷端补偿K热电偶数字转换器 1、MAX6675介绍 MAX6675执行冷端补偿并将来自K型热电偶的信号数字化。 数据以 12 位分辨率、SPI™ 兼容的只读格式输出。 该转换器可将温度解析为 0.25C,读数高达 +1024C,并且在 0C 至 +700C 的温度范围内具有 8 LSB 的热电偶精度。 MAX…...

Python基础知识汇总(字符串四)

目录 字母的大小写转换 lower()方法 upper()方法 删除字符串中的空格和特殊字符 strip()方法...

C语言学习笔记——指针(初阶)

前言 指针可以说是C语言基础语法中最难的理解的知识之一,很多新手(包括我)刚接触指针时都觉得很难。在我之前发布的笔记中都穿插运用了指针,但是我一直没有专门出一期指针的笔记,这是因为我确实还有些细节至今还不太清…...

阿赵的MaxScript学习笔记分享十二《获取和导出各种数据》

大家好,我是阿赵,周日的早上继续分享MaxScript学习笔记,这是第十二篇,获取和导出各种数据 1、导出数据的目的 使用3DsMax建立3D模型后,很多时候需要输出模型到别的引擎去使用,常用的格式有Obj、FBX、SLT等…...

react-draggable实现拖拽详解

react-draggable属性常用属性属性列表事件列表举例首先安装 react-draggable实现移动希望小编写的能够帮助到你😘属性 常用属性 属性默认值介绍axisxhandle拖动的方向,可选值 x ,y,bothhandle无指定拖动handle的classposition无handle的位置&#xff0…...

01.进程和线程的区别

进程和线程的区别进程和线程是计算机中的两个核心概念,它们都是用来实现并发执行的方式,但是它们在实现并发的方式和资源管理方面有一些重要的区别。进程是一个程序的运行实例。每个进程都有自己的内存空间、代码、数据和系统资源(如文件描述…...

逻辑优化-rewrite

简介 逻辑综合中的rewrite算法是一种常见的优化算法,其主要作用是通过对逻辑电路的布尔函数进行等效变换,从而达到优化电路面积、时序和功耗等目的。本文将对rewrite算法进行详细介绍,并附带Verilog代码示例。 一、算法原理 rewrite算法的…...

文件传输与聊天系统设计

技术:Java等摘要:本文介绍了一种基于TCP/IP协议使用Socket技术实现的聊天室系统,包括私聊功能和文件传输功能,对系统的主要模块进行了分析,并对系统实现过程中遇到的关键性技术进行了阐述,最后对系统进行了…...

蓝桥杯第十四届校内赛(第三期) C/C++ B组

一、填空题 (一)最小的十六进制 问题描述   请找到一个大于 2022 的最小数,这个数转换成十六进制之后,所有的数位(不含前导 0)都为字母(A 到 F)。   请将这个数的十进制形式作…...

有关平方或高次方的公式整理一元高次方程的求解

Part.I Introduction 这篇博文记录一下数学中常用的有关平方或高次方的一些公式。 Chap.I 一些结论 下面一部分汇总了一些重要的结论 完全平方公式:(ab)2a22abb2(ab)^2a^22abb^2(ab)2a22abb2平方差公式:a2−b2(ab)(a−b)a^2-b^2(ab)(a-b)a2−b2(ab)(…...

Java笔记3

ArrayListArrayList<String> list new Arraylist<>();<>是泛型表示存放的数据类型&#xff0c;注意不能是基本数据类型&#xff1b;增删改查增&#xff1a;add 返回值为true删&#xff1a;remove 1.直接删元素2.根据索引删元素改&#xff1a;set&#xff08…...

Leetcode.2202 K 次操作后最大化顶端元素

题目链接 Leetcode.2202 K 次操作后最大化顶端元素 Rating &#xff1a; 1717 题目描述 给你一个下标从 0开始的整数数组 nums&#xff0c;它表示一个 栈 &#xff0c;其中 nums[0]是栈顶的元素。 每一次操作中&#xff0c;你可以执行以下操作 之一 &#xff1a; 如果栈非空…...

JAVA知识点全面总结3:String类的学习

三.String类学习 1.String&#xff0c;StringBuffer&#xff0c;StringBuilder的区别&#xff1f; 2.字符串拼接用加号的原理 &#xff1f; 3.字符串常量池如何理解&#xff1f; 4.String的intern方法理解&#xff1f; 5.String的equals方法和compareTo方法的使用&#xf…...

Eureka注册中心和Nacos注册中心详解以及Nacos与Eureka有什么区别?

目录&#xff1a;前言Eureka注册中心Nacos注册中心Nacos与Eureka有什么区别&#xff1f;前言提供接口给其它微服务调用的微服务叫做服务提供者&#xff0c;而调用其它微服务提供的接口的微服务则是服务消费者。如果服务A调用了服务B&#xff0c;而服务B又调用了服务C&#xff0…...

Web3D发展趋势以及Web3D应用场景

1&#xff0c;Web3D发展趋势随着互联网的快速发展&#xff0c;Web3D技术也日渐成熟&#xff0c;未来发展趋势也值得关注。以下是Web3D未来发展趋势的七个方面&#xff1a;可视化和可交互性的增强&#xff1a;Web3D可以为三维数据提供可视化和可交互性的增强&#xff0c;将极大地…...

2023-3-4 刷题情况

按位与为零的三元组 题目描述 给你一个整数数组 nums &#xff0c;返回其中 按位与三元组 的数目。 按位与三元组 是由下标 (i, j, k) 组成的三元组&#xff0c;并满足下述全部条件&#xff1a; 0 < i < nums.length 0 < j < nums.length 0 < k < nums.l…...

前端面试总结

1.引言 最近参加了大量的招聘会&#xff0c;投递了大量的简历&#xff0c;整整体会了从“随便找个厂上一下”——“还是的找个大厂”——“没人要”——“急了急了,海投一波”——“工资有点尬”——“海投中…”。简单说一下自己的一些感受吧&#xff0c;现在的前端属实有点尴…...

【网络】每天掌握一个Linux命令 - iftop

在Linux系统中&#xff0c;iftop是网络管理的得力助手&#xff0c;能实时监控网络流量、连接情况等&#xff0c;帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者

抖音增长新引擎&#xff1a;品融电商&#xff0c;一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中&#xff0c;品牌如何破浪前行&#xff1f;自建团队成本高、效果难控&#xff1b;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

如何理解 IP 数据报中的 TTL?

目录 前言理解 前言 面试灵魂一问&#xff1a;说说对 IP 数据报中 TTL 的理解&#xff1f;我们都知道&#xff0c;IP 数据报由首部和数据两部分组成&#xff0c;首部又分为两部分&#xff1a;固定部分和可变部分&#xff0c;共占 20 字节&#xff0c;而即将讨论的 TTL 就位于首…...

Linux --进程控制

本文从以下五个方面来初步认识进程控制&#xff1a; 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程&#xff0c;创建出来的进程就是子进程&#xff0c;原来的进程为父进程。…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)

前言&#xff1a; 在Java编程中&#xff0c;类的生命周期是指类从被加载到内存中开始&#xff0c;到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期&#xff0c;让读者对此有深刻印象。 目录 ​…...

华为OD机考-机房布局

import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...

如何更改默认 Crontab 编辑器 ?

在 Linux 领域中&#xff0c;crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用&#xff0c;用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益&#xff0c;允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...