LinkedList源码

news/2024/5/9 17:57:46/文章来源:https://blog.csdn.net/m0_37450089/article/details/131073453

介绍

  • 基于双向链表实现
  • 线程不安全
  • 插入删除效率较高,但不支持随机查找
public class LinkedList<E>extends AbstractSequentialList<E>implements List<E>, Deque<E>, Cloneable, java.io.Serializable

image-20230606072823995

常量&变量

    // 元素数量transient int size = 0;/*** Pointer to first node.* Invariant: (first == null && last == null) ||*            (first.prev == null && first.item != null)*  头节点*/transient Node<E> first;/*** Pointer to last node.* Invariant: (first == null && last == null) ||*            (last.next == null && last.item != null)*  尾节点*/transient Node<E> last;

LinkedList 的底层数据结构为双向链表,每个节点包含两个引用,prev指向当前节点前一个节点,next指向当前节点后一个节点,可以从头结点遍历到尾结点,也可以从尾结点遍历到头结点。

image-20230606072853944

构造方法

    /*** Constructs an empty list.* 无参构造 创建一个空集合*/public LinkedList() {}/*** Constructs a list containing the elements of the specified* collection, in the order they are returned by the collection's* iterator.** @param  c the collection whose elements are to be placed into this list* @throws NullPointerException if the specified collection is null*/public LinkedList(Collection<? extends E> c) {//调用无参,创建一个空集合this();addAll(c);}

内部类

ListItr

ListItr类定义在LinkedList类的内部(作为普通内部类),它实现了ListIterator接口,具有迭代器的功能。

    private class ListItr implements ListIterator<E> {//上一次执行next()或previos()方法时的节点private Node<E> lastReturned;//下一次即将访问的元素(后继节点)private Node<E> next;//下一次要访问的元素的索引(后继节点的索引)private int nextIndex;//将修改次数modCount赋给expectedModCount  预期的修改次数  =  实际修改次数private int expectedModCount = modCount;ListItr(int index) {// assert isPositionIndex(index);//根据索引获得后继节点next = (index == size) ? null : node(index);//后继节点的索引nextIndex = index;}//判断是否有下一个元素可访问public boolean hasNext() {//nextIndex小于size表示仍然还有后继结点,如果大于等于size那么表示要么是尾结点,要么索引越界了return nextIndex < size;}//获取下一个访问的元素public E next() {checkForComodification();//如果没有下一个元素if (!hasNext())//抛出NoSuchElementException异常throw new NoSuchElementException();//保存当前遍历的节点lastReturned = next;//下个节点next = next.next;//索引加1nextIndex++;//返回旧next节点的元素return lastReturned.item;}//判断是否有上一个元素可访问public boolean hasPrevious() {//向前遍历,当索引大于0,表示前驱节点存在return nextIndex > 0;}//获取上一个访问的元素public E previous() {checkForComodification();if (!hasPrevious())throw new NoSuchElementException();lastReturned = next = (next == null) ? last : next.prev;nextIndex--;return lastReturned.item;}//获取下一个访问的元素在线性表中的索引public int nextIndex() {return nextIndex;}//获取上一个访问元素在线性表中的索引public int previousIndex() {return nextIndex - 1;}/*** 使用迭代器进行迭代的时候不能进行调用list.remove()或list.add()删除修改元素,否则会抛出ConcurrentModificationException异常* 所以如果要增加或删除元素需要使用迭代器Iterator内部的remove()和add()方法*///删除元素public void remove() {checkForComodification();if (lastReturned == null)throw new IllegalStateException();//后继节点Node<E> lastNext = lastReturned.next;//删除当前节点unlink(lastReturned);//next 和 上一次遍历的节点 是同一个对象 说明是向前遍历if (next == lastReturned)next = lastNext;elsenextIndex--;//置null 便于回收lastReturned = null;expectedModCount++;}public void set(E e) {if (lastReturned == null)throw new IllegalStateException();checkForComodification();lastReturned.item = e;}//添加public void add(E e) {checkForComodification();lastReturned = null;if (next == null)//当前节点是尾结点,直接在尾部添加linkLast(e);else//插入到next节点前linkBefore(e, next);nextIndex++;expectedModCount++;}public void forEachRemaining(Consumer<? super E> action) {Objects.requireNonNull(action);while (modCount == expectedModCount && nextIndex < size) {action.accept(next.item);lastReturned = next;next = next.next;nextIndex++;}checkForComodification();}final void checkForComodification() {if (modCount != expectedModCount)throw new ConcurrentModificationException();}}

ListItr类不仅可以遍历元素,还可以遍历元素时添加、删除元素

ListItr类定义在LinkedList的内部,每个ListItr对象隐式持有LinkedList对象的引用,该迭代器在遍历时对ListItr对象添加、删除、修改元素,都会影响到LinkedList对象

    public static void main(String[] args) {LinkedList<String> list=new LinkedList();list.add("aa");list.add("bb");System.out.println(list);ListIterator<String> iterator = list.listIterator();while (iterator.hasNext()) {String next = iterator.next();if (next.equals("aa")) {iterator.add("cc");}}System.out.println(list);ListIterator<String> iterator2 = list.listIterator();while (iterator2.hasNext()) {String next = iterator2.next();if (next.equals("bb")){iterator2.remove();}}System.out.println(list);ListIterator<String> iterator3 = list.listIterator();while (iterator3.hasNext()) {String next = iterator3.next();if (next.equals("cc")){iterator3.set("dd");}}System.out.println(list);}

image-20230606072957431

对集合使用迭代器遍历时,可以使用迭代器内部的remove()或add()方法对集合中元素进行增删操作

注:使用list的remove()或add()方法会报ConcurrentModificationException,list无set(E e)方法

image-20230606073009482

Node

Node类就是LinkedList中元素的包装类,表示LinkedList中的一个一个元素

    private static class Node<E> {//元素E item;//后节点Node<E> next;//前节点Node<E> prev;Node(Node<E> prev, E element, Node<E> next) {this.item = element;this.next = next;this.prev = prev;}}

DescendingIterator

为listitter .previous提供降序迭代器的适配器,即从LinkedList的列表末尾开始,逆序遍历进而到达列表头部。

    /*** Adapter to provide descending iterators via ListItr.previous*/private class DescendingIterator implements Iterator<E> {private final ListItr itr = new ListItr(size());public boolean hasNext() {return itr.hasPrevious();}public E next() {return itr.previous();}public void remove() {itr.remove();}}

LLSpliterator

用于并行流的可分割式迭代器

    /** A customized variant of Spliterators.IteratorSpliterator */static final class LLSpliterator<E> implements Spliterator<E> {static final int BATCH_UNIT = 1 << 10;  // batch array size incrementstatic final int MAX_BATCH = 1 << 25;  // max batch array size;final LinkedList<E> list; // null OK unless traversedNode<E> current;      // current node; null until initializedint est;              // size estimate; -1 until first neededint expectedModCount; // initialized when est setint batch;            // batch size for splitsLLSpliterator(LinkedList<E> list, int est, int expectedModCount) {this.list = list;this.est = est;this.expectedModCount = expectedModCount;}final int getEst() {int s; // force initializationfinal LinkedList<E> lst;if ((s = est) < 0) {if ((lst = list) == null)s = est = 0;else {expectedModCount = lst.modCount;current = lst.first;s = est = lst.size;}}return s;}public long estimateSize() { return (long) getEst(); }public Spliterator<E> trySplit() {Node<E> p;int s = getEst();if (s > 1 && (p = current) != null) {int n = batch + BATCH_UNIT;if (n > s)n = s;if (n > MAX_BATCH)n = MAX_BATCH;Object[] a = new Object[n];int j = 0;do { a[j++] = p.item; } while ((p = p.next) != null && j < n);current = p;batch = j;est = s - j;return Spliterators.spliterator(a, 0, j, Spliterator.ORDERED);}return null;}public void forEachRemaining(Consumer<? super E> action) {Node<E> p; int n;if (action == null) throw new NullPointerException();if ((n = getEst()) > 0 && (p = current) != null) {current = null;est = 0;do {E e = p.item;p = p.next;action.accept(e);} while (p != null && --n > 0);}if (list.modCount != expectedModCount)throw new ConcurrentModificationException();}public boolean tryAdvance(Consumer<? super E> action) {Node<E> p;if (action == null) throw new NullPointerException();if (getEst() > 0 && (p = current) != null) {--est;E e = p.item;current = p.next;action.accept(e);if (list.modCount != expectedModCount)throw new ConcurrentModificationException();return true;}return false;}public int characteristics() {return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;}}

常用方法

add

image-20230606073137530

    /*** Appends the specified element to the end of this list.** <p>This method is equivalent to {@link #addLast}.** @param e element to be appended to this list* @return {@code true} (as specified by {@link Collection#add})* 插入尾部,并返回true 与addLast方法等价*/public boolean add(E e) {linkLast(e);return true;}/*** Inserts the specified element at the specified position in this list.* Shifts the element currently at that position (if any) and any* subsequent elements to the right (adds one to their indices).** @param index index at which the specified element is to be inserted* @param element element to be inserted* @throws IndexOutOfBoundsException {@inheritDoc}*/public void add(int index, E element) {checkPositionIndex(index);if (index == size)//尾部添加linkLast(element);else//在索引对应的节点前插入elementlinkBefore(element, node(index));}

checkPositionIndex

    private void checkPositionIndex(int index) {//不符合条件 报错if (!isPositionIndex(index))throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}/*** Tells if the argument is the index of a valid position for an* iterator or an add operation.* 参数index是否符合条件*/private boolean isPositionIndex(int index) {return index >= 0 && index <= size;}

linkLast

在尾部添加元素

    /*** Links e as last element.*/void linkLast(E e) {// 获取尾部元素final Node<E> l = last;// 实例化一个新的节点,前一个节点为l,当前节点为传入的添加节点,下一个节点为nullfinal Node<E> newNode = new Node<>(l, e, null);// 将尾部节点进行更新(添加上新加入的节点)last = newNode;// 当尾部节点为空时,头节点即为新添加的节点if (l == null)first = newNode;// 否则,尾部节点的下一个为新添加的节点elsel.next = newNode;// 元素数量+1size++;// 修改次数+1modCount++;}

linkBefore

    /*** Inserts element e before non-null Node succ.* 在非空节点succ前,插入元素 e*/void linkBefore(E e, Node<E> succ) {// assert succ != null;//原index对应节点succ的前驱节点final Node<E> pred = succ.prev;//创建新的节点  pred <-- e --> succfinal Node<E> newNode = new Node<>(pred, e, succ);//succ的前驱节点为newNode   pred <-- e <--> succ succ.prev = newNode;if (pred == null)// e <--> succ first = newNode;else//pred的后继节点为newNode  pred <--> e <--> succ pred.next = newNode;size++;modCount++;}

addAll

image-20230606073253283

     /*** Appends all of the elements in the specified collection to the end of* this list, in the order that they are returned by the specified* collection's iterator.  The behavior of this operation is undefined if* the specified collection is modified while the operation is in* progress.  (Note that this will occur if the specified collection is* this list, and it's nonempty.)** @param c collection containing elements to be added to this list* @return {@code true} if this list changed as a result of the call* @throws NullPointerException if the specified collection is null* 将指定集合中的所有元素追加到此列表的末尾。*/public boolean addAll(Collection<? extends E> c) {return addAll(size, c);}/*** Inserts all of the elements in the specified collection into this* list, starting at the specified position.  Shifts the element* currently at that position (if any) and any subsequent elements to* the right (increases their indices).  The new elements will appear* in the list in the order that they are returned by the* specified collection's iterator.** @param index index at which to insert the first element*              from the specified collection* @param c collection containing elements to be added to this list* @return {@code true} if this list changed as a result of the call* @throws IndexOutOfBoundsException {@inheritDoc}* @throws NullPointerException if the specified collection is null* 将指定集合(Collection c)中的所有元素插入到此列表中,从指定的位置(index)开始。*/public boolean addAll(int index, Collection<? extends E> c) {//判断索引是否越界checkPositionIndex(index);//通过指定集合获得数组Object[] a = c.toArray();//数组的长度int numNew = a.length;//长度为空,直接返回失败if (numNew == 0)return false;//节点的前驱节点、后继节点Node<E> pred, succ;//直接从尾部添加该集合if (index == size) {//后继节点为null,前驱节点为尾节点succ = null;pred = last;} else {//指定索引对应的节点为后继节点,节点的前节点为前驱节点succ = node(index);pred = succ.prev;}//遍历数组for (Object o : a) {//类型转换@SuppressWarnings("unchecked") E e = (E) o;//构造新节点       pred  <-- eNode<E> newNode = new Node<>(pred, e, null);if (pred == null)//新节点为头节点  efirst = newNode;else//前驱节点的下一个节点为新节点  pred <--> epred.next = newNode;//为了下个循环,将新节点置为前驱节点pred = newNode;}//如果后继节点为null(尾部插入的情况),前驱节点就是尾结点if (succ == null) {// pred <--> elast = pred;} else {//前驱节点的后节点为后继节点   pred <--> e --> succpred.next = succ;//后继节点的前节点为前驱节点   pred <--> e <--> succsucc.prev = pred;}size += numNew;modCount++;return true;}

remove(int index)

image-20230606073315312

    /*** Removes the element at the specified position in this list.  Shifts any* subsequent elements to the left (subtracts one from their indices).* Returns the element that was removed from the list.** @param index the index of the element to be removed* @return the element previously at the specified position* @throws IndexOutOfBoundsException {@inheritDoc}* 删除指定下标的元素*/public E remove(int index) {// 检测下标是否越界checkElementIndex(index);// 调用unlink删除元素return unlink(node(index));}/*** Unlinks non-null node x.*/E unlink(Node<E> x) {// assert x != null;// 获取当前元素final E element = x.item;// 获取下一个节点final Node<E> next = x.next;// 获取上一个节点final Node<E> prev = x.prev;// 当上一个节点为null时,将当前节点的下一个节点设置为头节点if (prev == null) {first = next;// 不为null时,将上一个节点的下一个节点设置为当前节点的下一个节点(跳过当前元素),然后将当前节点的前一个节点设置为null,断开连接} else {prev.next = next;x.prev = null;}// 当下一个节点为null时,将尾节点设置为上一个节点if (next == null) {last = prev;// 否则将下一个节点的前一个节点设置为前一个节点,并且将当前节点的下一个节点设置为null,断开连接} else {next.prev = prev;x.next = null;}// 设置当前元素为nullx.item = null;// 元素数量-1size--;// 修改次数+1modCount++;// 返回当前元素return element;}

remove()

    /*** Retrieves and removes the head (first element) of this list.** @return the head of this list* @throws NoSuchElementException if this list is empty* @since 1.5* 删除头节点*/public E remove() {// 直接调用removeFirst,删除头节点return removeFirst();}/*** Removes and returns the first element from this list.** @return the first element from this list* @throws NoSuchElementException if this list is empty*/public E removeFirst() {// 获取头节点final Node<E> f = first;// 头节点为null时直接抛出if (f == null)throw new NoSuchElementException();// 调用删除头节点的方法return unlinkFirst(f);}/*** Unlinks non-null first node f.*/private E unlinkFirst(Node<E> f) {// assert f == first && f != null;// 获取当前元素final E element = f.item;// 获取下一个节点final Node<E> next = f.next;// 将当前元素设置为nullf.item = null;// 将下一个节点设置为nullf.next = null; // help GC// 因为为删除头节点,所以将头节点设置为下一个节点(跳过当前头节点)first = next;// 当下一个节点为null时,尾节点设置为nullif (next == null)last = null;// 否则下一个节点的前一个节点设置为null,断开与之前头节点的连接elsenext.prev = null;// 元素数量-1size--;// 操作次数+1modCount++;// 返回删除的元素return element;}

element

/*** Retrieves, but does not remove, the head (first element) of this list.** @return the head of this list* @throws NoSuchElementException if this list is empty* @since 1.5* 获取头节点但不删除,链表为null抛出异常*/public E element() {// 直接调用getFirst获取头节点返回return getFirst();}/*** Returns the first element in this list.** @return the first element in this list* @throws NoSuchElementException if this list is empty* 获取头节点*/public E getFirst() {// 获取头节点final Node<E> f = first;// 当头节点为null时抛出异常if (f == null)throw new NoSuchElementException();// 否则返回头节点的值return f.item;}

offer

    /*** Adds the specified element as the tail (last element) of this list.** @param e the element to add* @return {@code true} (as specified by {@link Queue#offer})* @since 1.5* 尾部添加指定元素*/public boolean offer(E e) {//直接调用add方法return add(e);}

poll

    /*** Retrieves and removes the head (first element) of this list.** @return the head of this list, or {@code null} if this list is empty* @since 1.5* 获取头节点并删除*/public E poll() {// 获取头节点final Node<E> f = first;// 当为null时直接返回null,否则调用unlinkFirstreturn (f == null) ? null : unlinkFirst(f);}

peek

    /*** Retrieves, but does not remove, the head (first element) of this list.** @return the head of this list, or {@code null} if this list is empty* @since 1.5* 获取头节点,但不删除,链表为null则返回null*/public E peek() {// 获取头节点final Node<E> f = first;// 头节点为null直接返回null,否则返回元素return (f == null) ? null : f.item;}

push

    /*** Pushes an element onto the stack represented by this list.  In other* words, inserts the element at the front of this list.** <p>This method is equivalent to {@link #addFirst}.** @param e the element to push* @since 1.6* 压入元素*/public void push(E e) {// 直接调用addFirst方法,addFirst调用了linkFirstaddFirst(e);}/*** Inserts the specified element at the beginning of this list.** @param e the element to add*/public void addFirst(E e) {linkFirst(e);}/*** Links e as first element.* 头部添加元素*/private void linkFirst(E e) {// 获取头节点final Node<E> f = first;// 实例化一个新的节点,上一个节点为null,当前节点为传入元素,下个节点为头节点final Node<E> newNode = new Node<>(null, e, f);// 将新的节点赋值给头节点first = newNode;// 当头节点为空时,尾节点也直接设置为新节点if (f == null)last = newNode;// 否则头节点的前一个节点为新节点elsef.prev = newNode;// 元素数量+1size++;// 修改次数+1modCount++;}

pop

    /*** Pops an element from the stack represented by this list.  In other* words, removes and returns the first element of this list.** <p>This method is equivalent to {@link #removeFirst()}.** @return the element at the front of this list (which is the top*         of the stack represented by this list)* @throws NoSuchElementException if this list is empty* @since 1.6* 弹出元素*/public E pop() {// 直接调用removeFirst方法,removeFirst进行判空,空抛出异常,然后调用unlinkFirstreturn removeFirst();}/*** Removes and returns the first element from this list.** @return the first element from this list* @throws NoSuchElementException if this list is empty*/public E removeFirst() {// 获取头节点final Node<E> f = first;// 头节点为null时直接抛出if (f == null)throw new NoSuchElementException();// 调用删除头节点的方法return unlinkFirst(f);}

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

chatgpt赋能python:Python定义父类的意义及用法

Python定义父类的意义及用法 Python是一种高级编程语言&#xff0c;具有强大的面向对象编程&#xff08;OOP&#xff09;能力。在OOP的设计中&#xff0c;定义一个父类可以让多个子类继承其属性和方法&#xff0c;从而提高代码重用率并简化程序的开发。 如何定义Python中的父…

EIoT能源物联网在工厂智能照明系统改造项目的应用 安科瑞 许敏

【摘要】&#xff1a;随着物联网技术的发展&#xff0c;许多场所针对照明合理应用物联网照明系统&#xff0c;照明作为工厂的重要能耗之一&#xff0c;工厂的照明智能化控制&#xff0c;如何优化控制、提高能源的利用率&#xff0c;达到节约能源的目的。将互联网的技术应用到工…

chatgpt赋能python:Python安装到C盘有什么方便之处?

Python安装到C盘有什么方便之处&#xff1f; 在进行Python编程时&#xff0c;安装Python到C盘是一个非常常见的做法。那么&#xff0c;将Python安装到C盘有哪些好处呢&#xff1f;下面&#xff0c;让我们来一一介绍。 1. 方便快捷 安装Python到C盘的好处之一就是非常方便&am…

直播教学答题卡(互动功能发起端JS-SDK)

本 SDK 主要包括发起答题卡、管理答题卡题库等功能。以下操作仅支持角色为讲师/嘉宾/助教/管理员的用户执行。 答题卡可以分为快速问答和普通答题卡。 快速问答只有单选和多选两种类型&#xff0c;没有具体的选项内容&#xff0c;最多可有 5 个选项。普通答题卡题目类型包括&a…

MySQ基本操作详解

MySQL的基本操作 首先sql操作中的关键字的是大小写不敏感的&#xff0c;create 和CREATE是一样的。 1.库操作 1. 1查看数据库 show databases;show 和databases 之间有一个或者多个空格注意是databases而不是database结尾分号是英文形式&#xff0c;分号在SQL中是表示一行执…

java设计模式(十五)责任链模式

目录 定义模式结构角色职责代码实现适用场景优缺点 定义 责任链模式(Chain of Responsibility) 使多个对象都有机会处理请求&#xff0c;从而避免请求的发送者和接受者之间的耦合关系。将这些对象连成一条链&#xff0c;并沿着这条链传递该请求&#xff0c;直到有对象能够处理…

chatgpt赋能python:使用Python安装Gensim:简单而强大的自然语言处理库

使用Python安装Gensim&#xff1a;简单而强大的自然语言处理库 Gensim是一个Python库&#xff0c;它为自然语言处理任务和文本处理任务提供了简单而强大的接口。它可以用于文本相似性计算、主题建模、词嵌入和其他自然语言处理任务。Gensim库的优点之一是其简单性和易用性。在…

chatgpt赋能python:Python如何降低memory的方法

Python如何降低memory的方法 Python已经成为了世界上最流行的编程语言之一&#xff0c;它在开发web应用、机器学习、数据分析等领域中拥有广泛的应用。然而&#xff0c;由于Python的内存管理机制&#xff0c;可能会导致程序的内存占用过高&#xff0c;影响系统的性能。在本文中…

chatgpt赋能python:Python安装教程:从下载到配置

Python安装教程&#xff1a;从下载到配置 Python作为一门高级编程语言&#xff0c;越来越受到开发人员的欢迎。Python的灵活性和易用性&#xff0c;让许多人选择Python作为他们的程序语言。本文将详细介绍Python安装教程&#xff0c;帮助初学者轻松入门。 1. 下载Python安装包…

评述:量子传感器正掀起一场商业革命

光子盒研究院出品 量子传感器利用原子和光的基本属性来对世界进行测量。粒子的量子状态对环境极为敏感&#xff0c;这对传感来说是一个优点、但对制造量子计算机来说则是一个问题。使用粒子作为探针的量子传感器可以比设计的或基于化学或电信号的经典设备更精确地量化加速度、磁…

Firefox插件(拓展)开发

目录 0、一些概念 1、创建一个项目 2、创建内容脚本 3、将拓展临时添加到浏览器中进行测试 3-1、CtrlShiftA 或&#xff1a; 3-2、选择调试附加组件 3-3、选择临时加载附加组件 3-4、选择我们项目中的 manifest.json 文件打开 3-5、如果打开成功&#xff1a; 4、继续开…

Spring高手之路1——深入理解与实现IOC依赖查找与依赖注入

本文从xml开始讲解&#xff0c;注解后面给出 文章目录 1. 一个最基本的 IOC 依赖查找实例2. IOC 的两种实现方式2.1 依赖查找&#xff08;Dependency Lookup&#xff09;2.2 依赖注入&#xff08;Dependency Injection&#xff09; 3. 在三层架构中的 service 层与 dao 层体会依…

chatgpt赋能python:Python安装Gurobi优化器详细步骤

Python安装Gurobi优化器详细步骤 如果你是一个数据科学家或者运筹学专业的研究者&#xff0c;你肯定会经常接触到优化问题。Gurobi是一个流行的线性与整数规划优化软件包&#xff0c;它提供了出色的线性规划和整数规划支持&#xff0c;速度快&#xff0c;准确度高&#xff0c;…

chatgpt赋能python:Python安装好后怎么写代码?

Python安装好后怎么写代码&#xff1f; Python是一种高级编程语言&#xff0c;已成为众多开发者的首选工具。根据一些统计数据&#xff0c;Python排名全球第三的流行语言&#xff0c;已经成为Web开发、数据科学和人工智能领域的首选语言。如果您刚刚安装了Python&#xff0c;那…

chatgpt赋能python:Python字典通过键找值:什么是Python字典?

Python字典通过键找值&#xff1a;什么是Python字典&#xff1f; Python字典是一种非常有用的数据类型&#xff0c;可以通过键值对方式存储和访问数据。它是Python的一种内置数据类型&#xff0c;可以在编程中非常方便地存储和操作数据。 Python字典可以存储任意类型的数据&a…

Linux命令学习之文本查看命令cat、head和tail

for i in {1..100} do echo $i >> good.txt done把1到100写入到good.txt文件中。接下来使用good.txt这个文件来演示查看文本查看命令。 cat man cat可以看一下帮助使用说明&#xff0c;按q可以退出。 cat是连接文件并把文件内容输出到标准输出上。cat good.txt就可以…

Linux 内存管理6——slab内存池的创建初始化过程

在上篇文章 中&#xff0c;笔者带大家从一个最简单的物理内存页开始&#xff0c;一步一步演进 slab cache 的架构&#xff0c;最终得到了一副 slab cache 完整的架构图&#xff1a; 在本文的内容中&#xff0c;笔者会带大家到内核源码实现中&#xff0c;来看一下 slab cache 在…

chatgpt赋能python:Python如何设置输入的SEO

Python如何设置输入的SEO Python是一种高级的编程语言&#xff0c;具有容易上手、可扩展和开源等特点&#xff0c;因此在软件开发过程中得到广泛的应用。然而&#xff0c;如果您想让您的Python项目在搜索引擎上获得更好的排名和流量&#xff0c;您需要考虑如何设置输入的SEO。…

初识TypeScript -基础一

前言 在开始工作之前&#xff0c;就听朋友提过TypeScript&#xff0c;之前也没多想学习&#xff0c;直到vue3出来之后&#xff0c;感觉TypeScript 后面会成为主流&#xff0c;只能硬着头皮学学吧。 读完本片文章&#xff0c;你会收获 1、TypeScript的历史及其优势 2、TypeScri…

chatgpt赋能python:Python如何抓取数据

Python如何抓取数据 介绍 Python是一种功能强大的编程语言&#xff0c;它被广泛使用于网络抓取和数据分析。无论您是想要从网站上抓取数据&#xff0c;还是使用API抓取数据&#xff0c;Python都是一种非常适合的工具。在本文中&#xff0c;我们将介绍Python如何抓取数据&…