集合-LinkedList

news2024/10/7 10:19:19

LinkedList

LinkedList的概述

LinkedList的底层使用双向链表实现。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YFvfuWIM-1681288911283)(E:\Java笔记\javaSE\集合(容器)(9)\集合\LinkedList.assets\image-20230406115511053.png)]

链表是一种线性数据结构,其中每个元素都是一个单独的对象,包含一个指向列表中下一个节点的引用。

它可以用于实现各种抽象数据类型,例如列表、堆栈、队列等。

LinkedList的优缺点

优点

  • 插入和删除操作的时间复杂度为O(1),相比于数组的O(n)更加高效。
  • 链表的大小可以动态调整,不像数组需要预先分配空间。
  • 链表的节点可以在内存中部连续存储,因此可以更加的灵活的利用内存空间。

缺点

  • 访问元素的时间复杂度为O(n),相比于数组的O(1)较低效。
  • 链表需要额外的空间来存储指向下一个节点的指针,因此占用的空间比数组更大。
  • 链表的随机访问效率比较低,因为需要从头开始遍历链表才能找到指定位置的节点。

LinkedList的创建方式

LinkedList linkedList = new LinkedList();
//向上转型
List linkedLists = new LinkedList();

常用方法,以及源码分析

方法返回类型解释
add(E e)boolean将指定元素添加到此列表的结尾
add(int index, E element)void将此列表中指定的位置插入指定的元素
addFirst(E e)void将指定元素插入此列表的开头
addLast(E e)void将指定元素添加到此列表的结尾
clear()void从此列表中移除所有元素
get(int index)E返回此列表中指定位置处的元素
getFirst()E返回此列表的第一个元素
remove()E获取并移除此列表的头(第一个元素)
remove(int index)E移除此列表中指定位置的元素
removeFirst()E移除并返回此列表的第一个元素
removelast()E移除并返回此列表的最后一个元素
set(int index,E element)E将此列表中指定位置的元素替换为指定的元素
size()int返回此列表的元素数

add(E e)

源码分析:

通过调用 linkLast(E e) 方法将元素添加到链表的末尾。

linkLast(E e) 方法创建一个新的节点,并将其插入到链表的末尾。如果链表为空,则将新节点设置为第一个节点。否则,将新节点链接到最后一个节点。最后,更新链表的大小和 modCount 变量。

	public boolean add(E e) {
        //调用linklast方法将元素添加到链表的尾端
    	linkLast(e);
        //添加成功,返回true
    	return true;
	}
	void linkLast(E e) {
        //获取链表的最后一个节点
        final Node<E> l = last;
        //创建最后一个节点,他的前驱节点是l,后去节点为null,数据为e
        final Node<E> newNode = new Node<>(l, e, null);
        //将链表的尾节点指向新节点
        last = newNode;
        //判断节点是否为null
        if (l == null)
            //为null则将节点指向新节点
            first = newNode;
        else
            //如果不为null,将原尾节点的后继节点指向新节点
            l.next = newNode;
        //聊表的大小加1
        size++;
        //修改计数器
        modCount++;
    }

案例:

public static void main(String[] args) {
        LinkedList linkedList = new LinkedList();
    	//添加数据
        linkedList.add("张三");
        linkedList.add("李四");
    	//输出此列表
        System.out.println(linkedList);
    }

add(int index, E element)

源码分析:

将元素添加到指定位置

public void add(int index, E element) {
   		 //检查索引是否越界
        checkPositionIndex(index);
		//索引与长度相等
        if (index == size)
            //在链表尾部添加数据
            linkLast(element);
        else
            //在指定位置之前添数据
            linkBefore(element, node(index));
    }

    private void checkPositionIndex(int index) {
        //判断索引是否合法
        if (!isPositionIndex(index))
            //不合法则抛出下标越界异常
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }

    void linkLast(E e) {
        //获取链表的最后一个节点
        final Node<E> l = last;
        //创建一个新的节点,他的前驱节点是l,后去节点为null,数据为e
        final Node<E> newNode = new Node<>(l, e, null);
        //将链表的最后一个节点指向新节点
        last = newNode;
        //判断链表是否为null
        if (l == null)
            //将第一个节点指向新节点
            first = newNode;
        //如果不为null
        else
            //将最后一个节点的下一个节点指向新节点
            l.next = newNode;
        //链表大小加1
        size++;
        //修改计数器加1
        modCount++;
    }
    void linkBefore(E e, Node<E> succ) {
        //获取指定位置的前一个节点
        final Node<E> pred = succ.prev;
        //创建一个新节点
        final Node<E> newNode = new Node<>(pred, e, succ);
        //将指定位置的前一个节点的下一个节点指向新节点
        succ.prev = newNode;
        //如果指定位置的前一个节点为null,
        if (pred == null)
            //将第一个节点指向新节点
            first = newNode;
        //如果指定位置的前一个节点不为null
        else
            //将前一个节点的下一个节点指向新节点
            pred.next = newNode;
        //链表大小加1
        size++;
        //修改计数器加1
        modCount++;
    }

案例:

public static void main(String[] args) {
    LinkedList linkedList = new LinkedList();
    linkedList.add("张三");
    linkedList.add("李四");
    System.out.println(linkedList);
    //位置1,添加数据
    linkedList.add(1,"王五");
    System.out.println(linkedList);
}

addFirst(E e)

源码分析:

将指定元素插入到此列表的开头

public void addFirst(E e) {
    // 在链表的头部添加一个新节点
    linkFirst(e);
}
private void linkFirst(E e) {
    // 获取头节点
	final Node> f = first;
	// 创建一个新节点,它的前驱节点为null,数据为e,后继节点为头节点f
	final Node> newNode = new Node<>(null, e, f);
	// 将头节点指向新节点
	first = newNode;
	// 如果头节点为null,说明
	if (f == null)
        //链表为空,将尾节点指向新节点
		last = newNode;
	// 否则将头节点的前驱节点指向新节点
	else
		f.prev = newNode;
	// 链表长度加1
	size++;
	// 修改次数加1
	modCount++;
  }

案例:

public static void main(String[] args) {
    LinkedList linkedList = new LinkedList();
    linkedList.add("张三");
    linkedList.add("李四");
    System.out.println(linkedList);

    linkedList.add(1,"王五");
    System.out.println(linkedList);
	//列表开头添加数据
    linkedList.addFirst("赵六");
    System.out.println(linkedList);

}

addLast(E e)

源码分析:

将指定元素添加到此列表的结尾

 public void addLast(E e) {
     //在链表的尾部添加一个新节点
        linkLast(e);
    }
void linkLast(E e) {
        //获取链表的最后一个节点
        final Node<E> l = last;
        //创建一个新的节点,他的前驱节点是l,后去节点为null,数据为e
        final Node<E> newNode = new Node<>(l, e, null);
        //将链表的最后一个节点指向新节点
        last = newNode;
        //判断链表是否为null
        if (l == null)
            //将第一个节点指向新节点
            first = newNode;
        //如果不为null
        else
            //将最后一个节点的下一个节点指向新节点
            l.next = newNode;
        //链表大小加1
        size++;
        //修改计数器加1
        modCount++;
    }

案例:

public static void main(String[] args) {
    LinkedList linkedList = new LinkedList();
    linkedList.add("张三");
    linkedList.add("李四");
    System.out.println(linkedList);

    linkedList.add(1,"王五");
    System.out.println(linkedList);

    linkedList.addFirst("赵六");
    System.out.println(linkedList);
	//列表结尾添加数据
    linkedList.addLast("唐七");
    System.out.println(linkedList);
}

clear():

源码分析:

从此列表中移除所有元素

public void clear() {
    // 遍历链表中的每一个节点
    for (Node<E> x = first; x != null; ) {
        // 保存当前节点的下一个节点
        Node<E> next = x.next;
        // 将当前节点的数据项置为null
        x.item = null;
        // 将当前节点的前驱和后继节点都置为null
        x.next = null;
        x.prev = null;
        // 将当前节点指向下一个节点
        x = next;
    }
    // 将链表的头节点和尾节点都置为null
    first = last = null;
    // 将链表的大小置为0
    size = 0;
    // 修改计数器
    modCount++;
}

案例:

public static void main(String[] args) {
    LinkedList linkedList = new LinkedList();
    
    linkedList.add("张三");
    linkedList.add("李四");
    linkedList.add(1,"王五");
    linkedList.addFirst("赵六");
    linkedList.addLast("唐七");
    System.out.println(linkedList);

    //清除此列表数据
    linkedList.clear();
    System.out.println(linkedList);;
}

get(int index)

源码分析:

返回此列表中指定位置处的元素

public E get(int index) {
    //校验索引是否合法
    checkElementIndex(index);
    //返回该索引对应的节点的数据
    return node(index).item;
}
private void checkPositionIndex(int index) {
        //判断索引是否合法
        if (!isPositionIndex(index))
            //不合法则抛出下标越界异常
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }
Node<E> node(int index) {
      // 如果要查找的节点在链表的前半部分
        if (index < (size >> 1)) {
            // 从头节点开始遍历
            Node<E> x = first;
            // 遍历到要查找的节点
            for (int i = 0; i < index; i++)
                // 指针指向下一个节点
                x = x.next;
            // 返回查找到的节点
            return x;
            // 如果要查找的节点在链表的后半部分
        } else {
            // 从尾节点开始遍历
            Node<E> x = last;
            // 遍历到要查找的节点
            for (int i = size - 1; i > index; i--)
                // 指针指向上一个节点	
                x = x.prev;
            // 返回查找到的节点
            return x;
        }
    }

案例:

public static void main(String[] args) {
    LinkedList linkedList = new LinkedList();
    linkedList.add("张三");
    linkedList.add("李四");
    linkedList.add(1,"王五");
    linkedList.addFirst("赵六");
    linkedList.addLast("唐七");
    System.out.println(linkedList);

    //获取指定位置的数据
    System.out.println(linkedList.get(2));
}

getFirst()

源码分析:

返回此列表的第一个元素

public E getFirst() {
    //获取链表的头节点
    final Node<E> f = first;
    //如果头节点为null
    if (f == null)
        //抛出NoSuchElementException异常
        throw new NoSuchElementException();
    //返回头节点的数据
    return f.item;
}

案例:

public static void main(String[] args) {
    LinkedList linkedList = new LinkedList();
    linkedList.add("张三");
    linkedList.add("李四");
    linkedList.add(1,"王五");
    linkedList.addFirst("赵六");      
    linkedList.addLast("唐七");
    System.out.println(linkedList);
    //获取此列表的第一个节点
    System.out.println(linkedList.getFirst());

}

remove()

源码分析:

获取并移除此里列表的头(第一个元素)

public E remove() {
    //调用移除第一个元素方法
    return removeFirst();
}
public E removeFirst() {
    // 获取链表的头节点
    final Node<E> f = first;
    // 如果头节点为空,
    if (f == null)
        //抛出NoSuchElementException异常
        throw new NoSuchElementException();
    // 返回调用调用unlinkFirst方法删除头节点并返回删除的元素
    return unlinkFirst(f);
}
 private E unlinkFirst(Node<E> f) {
    // assert f == first && f != null;
     // 获取头节点的元素
    final E element = f.item;
     // 获取头节点的下一个节点
    final Node<E> next = f.next;
     // 将头节点的元素置为空
    f.item = null;
     // 将头节点的下一个节点置为空,以便垃圾回收
    f.next = null; // help GC
     // 将链表的头节点指向原头节点的下一个节点
    first = next;
     // 如果原头节点的下一个节点为空
    if (next == null)
        //将链表的尾节点也置为空
        last = null;
    else
        // 否则将原头节点的下一个节点的前一个节点置为空
        next.prev = null;
     // 链表的大小减1
    size--;
     // 修改计数器加1
    modCount++;
     // 返回删除的元素
    return element; 
}

案例:

public static void main(String[] args) {
    LinkedList linkedList = new LinkedList();
    linkedList.add("张三");
    linkedList.add("李四");
    linkedList.add(1,"王五");
    linkedList.addFirst("赵六");
    linkedList.addLast("唐七");
    
    //获取并移除此列表的第一个节点
    System.out.println(linkedList.remove());
    //输出此列表的全部数据
    System.out.println(linkedList);
}

remove(int index)

源码分析:

移除指定列表中的指定位置的元素

//删除指定位置的节点
public E remove(int index) {
    // 检查索引是否越界
    checkElementIndex(index);
    // 删除并返回指定位置的节点
    return unlink(node(index));
}
// 检查索引是否越界
private void checkElementIndex(int index) {
    // 如果索引越界
    if (!isElementIndex(index))
        //则抛出IndexOutOfBoundsException异常
        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
// 删除指定节点
E unlink(Node<E> x) {
    // 获取节点的值	
    final E element = x.item;
    // 获取下一个节点
    final Node<E> next = x.next;
    // 获取上一个节点
    final Node<E> prev = x.prev;

    // 如果上一个节点为空
    if (prev == null) {
        // 将下一个节点设为头节点
        first = next;
    } else {
	    // 将上一个节点的下一个节点设为当前节点的下一个节点
        prev.next = next;
        // 将当前节点的上一个节点设为空
        x.prev = null;
    }

    // 如果下一个节点为空
    if (next == null) {
        // 将上一个节点设为尾节点
        last = prev;
    } else {
        // 将下一个节点的上一个节点设为当前节点的上一个节点
        next.prev = prev;
        // 将当前节点的下一个节点设为空
        x.next = null;
    }
	
    // 将当前节点的值设为空
    x.item = null;
    // 链表大小减一
    size--;
    // 修改次数加一
    modCount++;
    // 返回删除的节点的值
    return element;
}

// 获取指定位置的节点
Node<E> node(int index) {
    
	// 如果索引小于链表大小的一半
    if (index < (size >> 1)) {
         // 从头节点开始遍历
        Node<E> x = first;
        for (int i = 0; i < index; i++)
            // 遍历到指定位置
            x = x.next;
        // 返回指定位置的节点
        return x;
   // 如果索引大于等于链表大小的一半
    } else {
        // 从尾节点开始遍历
        Node<E> x = last;
        for (int i = size - 1; i > index; i--)
            // 遍历到指定位置
            x = x.prev;
        // 返回指定位置的节点
        return x;
    }
}

案例:

public static void main(String[] args) {
    LinkedList linkedList = new LinkedList();
    linkedList.add("张三");
    linkedList.add("李四");
    linkedList.add(1,"王五");
    linkedList.addFirst("赵六");
    linkedList.addLast("唐七");

    //移除此列表的指定位置的节点
    System.out.println(linkedList.remove(1));
    //输出此列表的全部数据
    System.out.println(linkedList);
}

removeFirst()

源码分析:

移除并返回列表的第一个元素

// 删除链表的头节点
public E removeFirst() {
    // 获取头节点
    final Node<E> f = first;
    // 如果头节点为空,
    if (f == null)
        //抛出NoSuchElementException异常
        throw new NoSuchElementException();
    // 否则,调用unlinkFirst方法删除头节点
    return unlinkFirst(f);
}
 private E unlinkFirst(Node<E> f) {
    // assert f == first && f != null;
     // 获取头节点的元素
    final E element = f.item;
     // 获取头节点的下一个节点
    final Node<E> next = f.next;
     // 将头节点的元素置为空
    f.item = null;
     // 将头节点的下一个节点置为空,以便垃圾回收
    f.next = null; // help GC
     // 将链表的头节点指向原头节点的下一个节点
    first = next;
     // 如果原头节点的下一个节点为空
    if (next == null)
        //将链表的尾节点也置为空
        last = null;
    else
        // 否则将原头节点的下一个节点的前一个节点置为空
        next.prev = null;
     // 链表的大小减1
    size--;
     // 修改计数器加1
    modCount++;
     // 返回删除的元素
    return element; 
}

案例:

public static void main(String[] args) {
    LinkedList linkedList = new LinkedList();
    linkedList.add("张三");
    linkedList.add("李四");
    linkedList.add(1,"王五");
    linkedList.addFirst("赵六");
    linkedList.addLast("唐七");

    //移除并返回列表的第一个元素
    System.out.println(linkedList.removeFirst());
    //输出此列表的全部数据
    System.out.println(linkedList);
}

removelast()

源码分析:

移除并返回此列表最后一个元素

// 从链表的尾部删除一个节点
public E removeLast() {
    // 获取尾节点
    final Node<E> l = last;
    // 如果尾节点为空
    if (l == null)
        //抛出NoSuchElementException异常
        throw new NoSuchElementException();
    // 调用unlinkLast方法删除尾节点
    return unlinkLast(l);
}
// 删除链表中的一个节点
private E unlinkLast(Node<E> l) {
    // assert l == last && l != null;
    // 获取节点的数据
    final E element = l.item;
    // 获取节点的前一个节点
    final Node<E> prev = l.prev;
    // 将节点的数据置为空
    l.item = null;
    // 将节点的前一个节点置为空	
    l.prev = null; // help GC
    // 将尾节点指向前一个节点
    last = prev;
    // 如果前一个节点为空
    if (prev == null)
        // 将头节点置为空
        first = null;
    else
        // 将前一个节点的指针置为空
        prev.next = null;
    // 链表大小减1
    size--;
    // 修改计数器加1
    modCount++;
    // 返回被删除节点的数据
    return element;
}

案例:

public static void main(String[] args) {
    LinkedList linkedList = new LinkedList();
    linkedList.add("张三");
    linkedList.add("李四");
    linkedList.add(1,"王五");
    linkedList.addFirst("赵六");
    linkedList.addLast("唐七");

    //移除并返回列表的最后一个元素
    System.out.println(linkedList.removeLast());
    //输出此列表的全部数据
    System.out.println(linkedList);
}

set(int index,E element)

源码分析:

将此列表中指定位置的元素替换为指定的元素

public E set(int index, E element) {
    //检查索引是否越界
    checkElementIndex(index);
    // 获取指定索引的节点
    Node<E> x = node(index);
    // 获取原节点的值
    E oldVal = x.item;
    // 将指定索引的节点的值设置为新值
    x.item = element;
    // 返回原节点的值
    return oldVal;
}
 private void checkElementIndex(int index) {
     // 如果索引越界
    if (!isElementIndex(index))
        //抛出IndexOutOfBoundsException异常
        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
    Node<E> node(int index) {
        // assert isElementIndex(index);
		// 如果指定索引小于链表长度的一半,则从头节点开始遍历
        if (index < (size >> 1)) {
            Node<E> x = first;
            for (int i = 0; i < index; i++)
                x = x.next;
            return x;
            // 如果索引大于等于链表长度的一半,则从尾节点开始遍历
        } else {
            Node<E> x = last;
            for (int i = size - 1; i > index; i--)
                x = x.prev;
            return x;
        }
    }

案例:

public static void main(String[] args) {
    LinkedList linkedList = new LinkedList();
    linkedList.add("张三");
    linkedList.add("李四");
    linkedList.addFirst("赵六");
    linkedList.addLast("唐七");
    System.out.println("原数据:"+linkedList);

    //指定位置的值替换为指定的元素
    linkedList.set(2,"小明");
    System.out.println("修改后的数据:"+linkedList);
}

size()

源码分析:

返回此列表的元素个数

public int size() {
    //返回链表的长度
    return size;
}

案例:

public static void main(String[] args) {
    LinkedList linkedList = new LinkedList();
    linkedList.add("张三");
    linkedList.add("李四");
    linkedList.addFirst("赵六");
    linkedList.addLast("唐七");

    System.out.println(linkedList.size());
}

线程安全

LinkedList不是线程安全的,如果需要在多线程环境下使用LinkedList,需要使用Collections.synchronizedList方法将其包装成线程安全的List

List<String> linkedList = new LinkedList<>();
List<String> synchronizedList = Collections.synchronizedList(linkedList); 

观众老爷看完觉得不错点个赞
在这里插入图片描述

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

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

相关文章

安装Nginx——docker安装

使用docker安装Nginx 1.开启docker systemctl start docker docker search nginx[rootlocalhost ~]# systemctl start docker //开启docker [rootlocalhost ~]# docker search nginx //搜素镜像 2. docker pull nginxdocker imagesdocker run -…

如何将录音转成文字?

在现代社会中&#xff0c;随着语音技术的不断发展和普及&#xff0c;将录音转换为文字变得越来越容易。无论是为了记录会议、面试、讲座、采访&#xff0c;还是为了记录个人的思考和想法&#xff0c;将录音转换为文字是一种方便快捷的方式。本文将介绍几种将录音转换为文字的方…

计算机系统结构教程-第七章-储存系统笔记(1)

7.1储存系统的层次结构 概述 理想的储存器&#xff1a;容量大、速度快、价格低。 但以上三种要求在实际应用中是相互矛盾&#xff1a; &#xff08;1&#xff09;速度快&#xff0c;价格高。 &#xff08;2&#xff09;容量大&#xff0c;价格低。 &#xff08;3&#xf…

ESLint检测VUE和JSON文件

ESLint 默认只支持检测JS文件中的文件&#xff0c;无法识别其它类型的文件&#xff0c;如果需要检测其它类型的文件就需要安装并指定对应的处理器&#xff0c;有点类似webpack的loader 处理vue文件 使用ESLint默认的处理器处理Vue文件大多数情况下会收到一个这样的错误。 Pa…

贪心算法

章节目录&#xff1a;一、算法介绍二、应用场景-集合覆盖问题2.1 问题引出2.2 思路分析2.3 代码示例三、结束语一、算法介绍 贪心算法&#xff08;greedy algorithm &#xff0c;又称贪婪算法&#xff09;是指&#xff0c;在对问题求解时&#xff0c;总是做出在当前看来是最好的…

Vue04_事件绑定_methods

v-on:事件名"表达式" methods: 定义回调函数 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title> </head> <body><div id"app"><!--eve…

12、Qt生成dll方式-libs方式使用

Qt创建dll&#xff0c;使用LIBS -L$PWD -lxxx的方式调用dll 一、创建项目 1、打开Qt->新建文件->其他项目->Empty qmake Project->Choose... 2、输入项目名->选择位置->下一步 3、MinGW->下一步 4、默认&#xff0c;完成 5、在.pro中添加TEMPLATE sub…

C51单片机按键控制流水灯模式(定时器版本)以及定时器时钟

上篇文章我们学了关于定时器的三大组成部分及许多寄存器的概念问题&#xff0c;这篇文章我们就要开始讲解实操部分。 首先&#xff0c;我们先来看看本文最后写成的代码&#xff1a; 以上三张是代码的主函数&#xff0c;此外&#xff0c;代码中还需用到的独立按键检测代码在下面…

【Linux】回车与换行的区别+简单实现倒计时和进度条(学以致用)

前言&#xff1a;本文主要讲解回车与换行的区别&#xff0c;理解完回车与换行的区别后&#xff0c;我们将带大家实现一个简单的倒计时程序&#xff0c;会利用到本文学习的回车与换行&#xff0c;做到学以致用。 文章目录一.理解回车与换行(1)\r和\n都存在(2)\r和\n都不存在(3) …

单片机作业第4章

1.SJMP rel 无条件跳转指令 rel是相对偏移量&#xff0c;是一个单字节的带符号8位二进制补码数&#xff0c;所以它能实现的程序跳转是双向的。 2. (单选题, 2分)当CPU响应外部中断0 (INT0)的中断请求后&#xff0c;程序计数器PC的内容是 &#xff08; A &#xff09; 。 A…

性能优化之-事件代理

js中的事件委托或是事件代理简单理解 事件委托也叫事件代理&#xff0c;“事件代理”即是把原本需要绑定在子元素的响应事件&#xff08;click、keydown…&#xff09;委托给父元素&#xff0c;让父元素担当事件监听的职务。事件代理的原理是DOM元素的事件冒泡。 概述&#x…

Direct3D 12——灯光——法向量

a:平面法线着色 b:顶点法线着色 c:像素着色 平面法线&#xff08;face normal,由于在计算机几何学中法线是有方向的向量&#xff0c;所以也有将normal译作法向量&#xff09; 是 一种描述多边形朝向&#xff08;即正交于多边形上所有点&#xff09;的单位向量。 曲面法线&a…

[C++]vector类的模拟实现和相关函数的详解

文章目录架构实现默认构造函数构造函数拷贝构造为什么不能使用memcpy()进行拷贝&#xff08;浅拷贝问题&#xff09;析构函数赋值重载[]迭代器begin && end操作函数size() && capacity()push_back()reserve()resize()insert()erase()完整代码架构 首先由于自定…

RabbitMQ消息队列实战(4)—— spring-boot-starter-amqp中消息的可靠性传输和确认机制

在上一篇文章中&#xff0c;笔者整理了从消息生产出来到消费结束的整个生命周期过程中&#xff0c;为了确保消息能够可靠到达或者消费&#xff0c;我们需要在哪些环节进行哪些处理&#xff0c;同时也展示了使用Java原生代码怎么样在这些环节进行处理。本文主要介绍使用spring b…

java静态代码块

在 Java中&#xff0c;每个类都有一个静态的代码块&#xff0c;用来描述类的构造函数和实例变量。在 java. util. Static中定义了一个静态代码块&#xff0c;在该代码块中&#xff0c;类的构造函数和实例变量都是不可以被修改的。 一个类包含了由它自己定义的静态代码块&#x…

【论文阅读】Self-paced Multi-view Co-training

论文下载 bib: ARTICLE{MaMeng2020SPamCo, title {Self-Paced Multi-View Co-Training}, author {Fan Ma and Deyu Meng and Xuanyi Dong and Yi Yang}, journal {J. Mach. Learn. Res.}, year {2020}, volume {21}, number {1}, numpages {1--38} }目录1.…

Kubernetes中的Calico网络

文章目录1 介绍2 环境部署3 IPIP模式3.1 测试环境3.2 ping包网络转发4 BGP模式4.1 测试环境4.2 ping网络转发5 两种模式对比1 介绍 Calico网络的大概思路&#xff0c;即不走Overlay网络&#xff0c;不引入另外的网络性能损耗&#xff0c;而是将转发全部用三层网络的路由转发来…

GPSS【实践 01】Developing a Greenplum Streaming Server Client 自定义GPSS客户端开发实例

自定义GPSS客户端开发流程1.GPSS是什么2.架构3.组件下载安装4.自定义客户端4.1 GPSS Batch Data API Service Definition4.2 Setting up a Java Development Environment4.3 Generating the Batch Data API Client Classes4.4 Coding the GPSS Batch Data Client4.4.1 Connect …

【论文笔记】Attention Augmented Convolutional Networks(ICCV 2019 入选文章)

目录 一、摘要 二、介绍 三、相关工作 卷积网络Convolutional networks&#xff1a; 网络中注意力机制Attention mechanisms in networks&#xff1a; 四、方法 1. 图像的自注意力Self-attention over images&#xff1a; 二维位置嵌入Two-dimensional Positional Enco…

redis 第一章

开始学习redis 之旅吧 关于redis 的介绍 redis 是一个开源的软件&#xff0c;可以存储结构化的数据在内存中&#xff0c;像内存数据库&#xff0c;缓存、消息中间件、流处理引擎。 redis 提供的数据结构像strings, hashes, lists, sets, sorted sets 。Redis具有内置复制、Lua…