jdk1.8 的ArrayList

JDK1.6 到JDK1.7,JDK1.8 ArrayList跟HashMap的变化 重点构造方法,有动扩容 (1)JDK1.6的构造方法 JDK1.8的构造方法 /** * 初始化没有指定list大小,第一次插入的时候确定list容量的大小 */ private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; /** * ArrayList with el... 阅读详情

这篇文章没有写完。以后继续更新。自己写给自己看的,有些不规范的地方:类名没有驼峰形式大写,方法或成员变量起名随意

一、概述

ArrayList是实现List接口的动态数组,所谓动态就是它的大小是可变的。实现了所有可选列表操作,并允许包括 null 在内的所有元素。除了实现 List 接口外,此类还提供一些方法来操作内部用来存储列表的数组的大小。

二、ArrayList 的重要成员变量

1.private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

无参构造函数在jdk1.6(包含)之前时是构造默认一个容量为10的数组,但是现在给定为空的数组。

2.transient Object[] elementData; 

elementData 表示底层组装的Object类型的数组。

3.private static final int DEFAULT_CAPACITY = 10;

默认容量大小是10,但是在无参构造方法中没有起到作用。目前在elementData扩容时用到了该参数。

但是为啥选择10?不是2的幂次方例如hashmap的16?我认为的原因是ArrayList在扩容时并没有类似hashmap的额外的开销而采用的数学技巧,可能根据人类十进制的惯性选择了一个任意的不能太小,也不能太大的10。

4. private int size;

表示当前ArrayList的大小(存储元素的数量)

5.protected transient int modCount = 0;

来自ArrayList的父类AbstractList。fail-fast机制。

6.private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

具体原因可以查看源码注释

/**
     * The maximum size of array to allocate. 要分配的最大数组大小。
     * Some VMs reserve some header words in an array. 一些虚拟机在数组中保留一些标题字
     * Attempts to allocate larger arrays may result in  尝试分配更大的数组可能会导致OutOfMemoryError
     * OutOfMemoryError: Requested array size exceeds VM limit  请求的阵列大小超出了VM限制
     */

三、ArrayList 的构造方法

1.无参构造方法

    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

2.参数为初始化数组大小(int)的构造方法

    public ArrayList(int initialCapacity) {
        if (initialCapacity > 0) {
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity);
        }
    }

其中:private static final Object[] EMPTY_ELEMENTDATA = {};

DEFAULTCAPACITY_EMPTY_ELEMENTDATA(默认容量[0]空元素数据) 和 EMPTY_ELEMENTDATA (空元素数据)都是空数组({}),为什么要初始化两个?不能替换使用吗?我觉得最大的意义是便于阅读源码。(具体原因还有待讨论,也许是原作者当时想问题时就用到了两个变量,就顺手定义了)。但是该方法关于和jdk1.7版本的性能改进请详见

https://blog.youkuaiyun.com/weixin_43390562/article/details/101236833

3.参数为集合的构造方法

    public ArrayList(Collection<? extends E> c) {
        elementData = c.toArray();
        if ((size = elementData.length) != 0) {
            // c.toArray might (incorrectly) not return Object[] (see 6260652)
            if (elementData.getClass() != Object[].class)
                elementData = Arrays.copyOf(elementData, size, Object[].class);
        } else {
            // replace with empty array.
            this.elementData = EMPTY_ELEMENTDATA;
        }
    }

其中有这样一句注释:c.toArray might (incorrectly) not return Object[] (see 6260652) 具体原因请详见

https://blog.youkuaiyun.com/gulu_gulu_jp/article/details/51457492

四、ArrayList 一些重要的成员方法

1.ArrayList的增

1.1 末尾增加 add()方法

首先判定是否需要扩容,如果需要则需要一个新的newlength空间的数组,以及数组.length的值复制,即空间复杂度为O(n),时间复杂度为O(n);不扩容则空间复杂度为O(0),时间复杂度为O(1).

private void ensureCapacityInternal(int minCapacity) {
        /** 首先判定是否为空,如果为空则重置目前需要的最小容量.(比较10和minCapacity,取最大值)
            ensureCapacityInternal方法addall()也用了。
            所以minCapacity的取值范围是[1,Integer.MAX_VALUE]
        */
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }

        ensureExplicitCapacity(minCapacity);
    }

    private void ensureExplicitCapacity(int minCapacity) {
        modCount++;// fast-fail 机制

        // overflow-conscious code
        /** 溢出感知代码
          *  minCapacity的值是有溢出风险的,ArrList没有做当minCapacity<0(向上溢出)时直接抛出异                            
          *  常的检查,而把检查下沉到 private static int hugeCapacity(int minCapacity) 方法中 
          * 了。通过观看源码上下文可以得出minCapacity=size+n ;elementData.length=size+x;其 
          *中size是当前容器里容纳的元素个数,n为要新添加的元素个数,x为当前容器里还可以容纳元素的 
          *个数。所以minCapacity - elementData.length > 0 可以转化为 n-x>0;可以肯定n和x都是自 
          *然数,所以这样写一定可以说明在数学意义上(如果溢出了就换算成数学意义上的值)                    
          *minCapacity> elementData.length,则表明数组需要扩容
        */
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);// 在这里minCapacity的值还可能是溢出的
    }

grow(int minCapacity) 方法实现的功能用一句话概括就是,如果 minCapacity 小于等于原数组的 1.5 倍,则扩容至原数组的 1.5 倍,如果 minCapacity 大于原数组的 1.5 倍,则扩容至 minCapacity。

 private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

    private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE :MAX_ARRAY_SIZE;
    }

 

2.2 插入增加 add(index, element);

同样需要判定是否扩容,但是无论是否扩容时间复杂度都是O(n-i)。

2.ArrayList的删除

private void fastRemove(int index) {
        modCount++;
        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        elementData[--size] = null; // clear to let GC do its work
    }

以上是主要的删除方法,无论是删除下标还是删除对象。最后都要走这个逻辑 。

删除方法都是先比较时间复杂度O(n)再删除(元素顺序前移)O(n)

但是有一些隐含坑,阿里规约也提到了:【强制】不要在 foreach 循环里进行元素的 remove/add 操作。remove 元素请使用 Iterator 方式,如果并发操作,需要对 Iterator 对象加锁。

具体可以看这篇博文:https://blog.youkuaiyun.com/Sun_flower77/article/details/78008491

总结:当需要循环删除时慎用ArrayList的remove方法,循环删除时采用for循环倒叙删除或者Iterator方式;删除自定义的类对象一定要重写equals和hashcode方法。

五、一些有趣的问题

1.参数为null会调用哪个方法?

public class hwbtest {
	public static void f(Integer integer) {
		System.err.println("Integer");
	}
	public static void f(int i) {
		System.err.println("int");
	}
	public static void f(String string) {
		System.err.println("String");
	}
	public static void main(String[] args) {
		f(null); // 编译报错,The method f(Integer) is ambiguous for the type hwbtest
	}

}

2.        ArrayList<String> arrayList = new ArrayList<>(null); 会怎样?

          编译不报错,运行报错。 Effective java:检查参数的有效性。 java源码里并没有对传入null的检查

3.阿里规约:【推荐】集合泛型定义时,在 JDK7 及以上,使用 diamond 语法或全省略。

public class hwbtest {
	/**
	 * 在eclipse上编辑的,为了防止eclipse报notused警报,所以打印每个实例
	 * @param args
	 */
	public static void main(String[] args) {
		/**
		 * 全省略方式,eclipse报警告信息。
		 * 调用add()方法只能添加String类型
		 */
		List<String> s0 = new ArrayList(10);
		System.err.println(s0);
		/**
		 * diamond方式,eclipse不报警告信息。
		 * 调用add()方法只能添加String类型
		 */
		List<String> s1 = new ArrayList<>(10);
		System.err.println(s1);
		/**
		 * 我自己编写代码的一般方式,eclipse不报警告信息。
		 * 调用add()方法只能添加String类型
		 */
		List<String> s2 = new ArrayList<String>(10);
		System.err.println(s2);
		/**
		 * eclipse报警告信息。
		 * 调用add()方法能添加任意引用类型元素
		 * 调用get(index) 方法可以获得元素
		 */
		List s3 = new ArrayList<String>(10);
		System.err.println(s3);
		/**
		 * eclipse报警告信息。
		 * 调用add()方法能添加任意引用类型元素
		 * 调用get(index) 方法可以获得元素
		 */
		List s4 = new ArrayList(10);
		System.err.println(s4);
		/**
		 * eclipse报警告信息。
		 * 不能调用add()方法
		 * 原因是s5不能确定到底可以容纳啥类型
		 */
		List<?> s5 = new ArrayList(10);
		s5.get(0);
		System.err.println(s5);
		// 总结:左边<>确定容器容纳元素类型,右边<> 不起多大作用
		// 左边<?>可以通过编译运行,但是无法调用add方法
		// diamond方式 个人觉得舒服(不报警告),而且少写右边<>中的类型
	}

}

4.private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; 那么数组的最大容量是多少呢?

   不考虑jvm的内存限制和不同版本jdk的设计,理论上在java中数组的最大容量是 Integer.MAX_VALUE。因为当时设计length属性时选择的是int。

public static void main(String[] args) {
		byte[] bs = new byte[Integer.MAX_VALUE-2];
		System.err.println(bs[Integer.MAX_VALUE-3]);
	}

由于我的机器的原因byte数组取的最大容量是 Integer.MAX_VALUE-2

private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ?Integer.MAX_VALUE :MAX_ARRAY_SIZE;
    }

上边是java ArrayList的一部分源码,可以发现返回的可能是 Integer.MAX_VALUE

5.b-a>0可以说明b>a吗?

  我们知道在java中int类型的取值范围是-2^31 至 2^31-1 ,也就是-2147483648 至2147483647。正整数超出2147483647范围后会出现循环取值的现象,也就是2147483647+1=2147483648溢出后回到了最小负整数-2147483648,2147483647+2=2147483649溢出后变成了-2147483648+1=-2147483647,依次类推。

public static void main(String[] args) throws SQLException, IOException, InterruptedException {
		int a = Integer.MAX_VALUE; int b = Integer.MIN_VALUE;
		System.err.println(b-a>0);
		System.err.println(b>a);
	}

由此可见在java中b-a>0不一定说明b>a。那什么情况下可以说明呢?(在数学意义上计算)|b-a|<2147483649(可以自己画有一个小缺口的的圆圈理解下,缺口的两端分别为最大值和最小值)。其实在ArrayList中有好多b-a>0的比较方式 ,我自己觉得用b>a的比较方式好点吧,毕竟少了一步减法运算而且肯定和数学意义的逻辑计算一致。

我上述的观点(b>a的比较方式好点)有点错误,在源码中有这样一句注释:overflow-conscious code。

其实可以看看这篇博文:https://www.jianshu.com/p/58f36f37405a

 

 

 

18:ArrayList 集合 JDK1.7 及 JDK1.8 版本的 扩容机制 、Vector 扩容机制 解读 及它们之间的区别总结: JDK1.7 、JDK1.8 的ArrayList 和 Vector 区别总结: JDK1.7的ArrayList的 扩容机制源码。JDK1.7的源码是 ,在实例化这个 ArrayList 集合对象的时候。不管 调用者初始化完ArrayList对象后 继不继续 使不使用,在初始化对象的时候,都会创建一个长度为 10 的 Object 的数组(elementData),当调用者继续使用时 添加元素 到集合中的容量 达到 elementData的当前最大容量时。 就会进行 对 elementData 阅读详情

相关推荐

iTunes登录协议全解析:从抓包到加密参数生成(含HTTPDebugger避坑指南)

本文深度解析iTunes登录协议,提供从环境搭建、绕过反调试机制到捕获网络流量的完整实战指南。重点剖析了如何利用HTTPDebugger等工具进行抓包,并详细解读了核心加密参数X-Apple-ActionSignature的生成逻辑,为网络安全研究员和协议分析工程师提供了一份详尽的逆向分析与协议复现教程。

weixin_28314575的博客 869

JDK1.8 ArrayList详解

1 ArrayList类定义 public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable { } 从ArrayList的定义可以得出: ArrayLi...

浅汐 558

FANUC机器人RSR与PNS功能深度解析及实战应用指南

本文深度解析了FANUC机器人RSR(远程程序启动)与PNS(程序号选择)两大核心功能。文章详细阐述了RSR的队列执行机制与PNS的二进制编码原理,提供了从硬件连接到参数配置的完整实战指南,并分享了混合使用策略与常见故障排除方法,旨在帮助工程师实现高效、稳定的生产线自动化程序调度。

neovim7hacker的博客 309

ArrayList学习(基于JDK 1.8)

1. ArrayList概述 回忆一下,遇到元素个数不确定时,就会使用ArrayList,而非数组 1.1 ArrayList的特性 同样的,还是通过阅读类注释了解ArrayList的特性 ArrayList的类注释,提供了以下信息 ArrayList实现了List接口,允许元素为null ArrayList是动态的list实现,提供了用于操作数组大小的方法 容量,指ArrayList中存储元素的数组大小;size,指ArrayList中的元素个数 向ArrayList中添加元素,其容量会

lucyLee的博客 614

数字图像处理基础实验(二):直方图均衡化

一、实验内容及原理 1、计算灰度图像的归一化直方图 具体内容:利用 OpenCV 对图像像素进行操作,计算归一化直方图.并在 窗口中以图形的方式显示出来 步骤: (1)初始化一个256大小的数组,存放图像中每级灰度值的像素点的个数 (2)遍历整张图像 (3)归一化数组 2、灰度图像直方图均衡处理 具体内容:通过计算归一化直方图,设计算法实现直方图均衡化处理。 步骤: (1)读取该像素点的灰度值 (...

lyd1995的博客 4525

ais信号接收设备_国内首款基于软件无线电技术的AIS基站投入测试使用

星网宇达子公司北京凯盾环宇科技有限公司经过多年的潜心研发,成功研制出国内首台基于软件无线电(SDR)的CATON 9011 AIS基站。该基站采用软件无线电技术,利用软件数字技术代替传统的模拟电路,大大的降低了模拟器件的使用率,提高了基站的可靠性和使用年限。CATON 9011 AIS基站研制依据ITU-R M.1371-5、IEC 62320-1、IEC 61162-1等国际标准,兼容...

weixin_29057163的博客 2334

ArrayList list = new ArrayList() 和List<String> list = new ArrayList<String>() 的区别

第一种用当前类作为引用类型,那么可以访问到ArrayList这个类中的所有公用方法。 第二种定义用ArrayList实现的接口List作为引用类型,那么通过list引用可以访问到接口中定义的方法。也就是说ArrayList这个类实现了List接口,除了要必须实现接口List中声明的方法外,还可以实现额外的一些方法。但是,第二种形式就无法调用的List接口以外的方法。是很好的面向接口编程的习惯。 比如你有这么一个方法供别人调用: public List getXXXList(){ List list

Leviiiiiiiii的博客 2640

学Simulink——基于Simulink的Buck-Boost变换器双闭环PI+抗饱和设计建模示例

本文详细介绍了基于Simulink的非反相Buck-Boost变换器双闭环控制设计方法。针对Buck-Boost变换器特有的右半平面零点(RHPZ)和控制挑战,提出了电压-电流双闭环PI控制架构,并集成抗积分饱和机制。通过Simulink建模,实现了主电路、电流内环PI、电压外环PI、PWM及占空比限幅等模块的搭建,验证了在输入电压跌落(20V→10V)和负载突变(2A→4A)等场景下的稳定性能。仿真结果表明,输出电压波动小于0.35V,恢复时间快于1ms,电感电流有效限幅。文章还讨论了工程实践要点和扩展方

xiaoheshang_123的博客 318

浅谈List<String> list=new ArrayList<>()与ArrayList<String> list=new ArrayList<>() 区别

习惯性的定义List<String> list=new ArrayList<>(),只知道ArrayList<String> list=new ArrayList<>()也是对的。 正常的操作是不会引起这个思考,定义为List<TreeNode<Integer>> list=new LinkedList<>()时,list.poll()确拒绝了我的调用 改为LinkedList<TreeNode>...

fanzhe的博客 5555

Buck电源设计常见的一些问题(一)半桥栅极驱动芯片共性失效问题

半桥驱动芯片主要用在器件可应用于电信,数据通信,便携式存储或更低电压系统中的电源转换器,半桥、全桥、推挽、同步降压,正激变换器和同步整流器等方面。当然难免会遇到不少问题。基本上我们在产品开发的过程中都遇到过栅极驱动芯片坏掉的情况,所以找了一些资料,学习学习。也查找查找原因。

小幽余生不加糖 2369

【2025最新版】Open3D 区域生长分割(python详细过程版)

点云区域生长分割算法的python详细过程版实现。博客长期更新,本文最新更新时间为:2025年3月23日。

点云侠的博客 9529

高并发下ArrayList空值(null)问题

对于ArrayList,有一篇blog专门的介绍,它不适用于多线程环境中,废话不多说,直接上代码让大家看个明白!public class ArrayListTest { @Test public void test() { List&lt;Person&gt; personList = new ArrayList&lt;&gt;(); for (in...

u011381576的博客 9326

基于PCL、Open3d、Easy3d 、VTK等常见开源库的QT开发

PCL+QT开发

阁楼 2万+

【源码 JDK 1.8】ArrayList的源码解读

【代码】【源码 JDK 1.8】ArrayList的源码解读。

Number_In的博客 916

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

jdk1.8中 ArrayList 底层数组到底是怎么扩容的

一、结论先行 ArrayList在JDK1.8与JDK1.7底层区别 JDK1.7:ArrayList像饿汉式,直接创建一个初始容量为10的数组 JDK1.8:ArrayList像懒汉式,一开始创建一个长度为0的数组,当添加第一个元 素时再创建一个始容量为10的数组 二、JDK1.8源码分析 1、ArrayList 属性 /** * 默认容量的大小 */ private static final int DEFAULT_CAPACITY = 10; /**

李光 未来科技 919

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

JDK1.7和JDK1.8下ArrayList()底层数组的默认长度

JDK1.7和JDK1.8下ArrayList()底层数组的默认长度 一、JDK1.7下ArrayList()初始化后的默认长度是10,源码如下: //无参构造方法 public ArrayList() { this(10); } public ArrayList(int initialCapacity) { super(); if (initi...

qq_36816062的博客 1584

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

arraylist如何检测某一元素是否为空_JDk1.8 util-ArrayList

本系列第一篇文章今天正式开始,会按照本人的时间情况进行更新阅读代码版本是JDK1.8,第一个包就先从util包开始吧下图是ArrayList的UML图,由于是本系列的第一篇文章,所以我们把其中涉及到的接口全部的介绍一下,对数据结构有整体的认识1 Iterable:提供了两种迭代器:一种是顺序迭代器Iterator, 一种是可分割迭代器Spliterator,该可分割迭代器主要是通过降低每次迭代的宽...

weixin_29495899的博客 633

ArrayList扩容机制JDK1.8

本题的所有的讲解都是基于JDK8 这道题考察了ArrayList的构造器和对扩容机制的了解,本篇博客基于此出发讲解ArrayList的扩容机制 想要做出这道题必须了解ArrayList的构造函数,ArrayList的构造函数总共有三个: ArrayList()构造一个空的数组。JDK7中构造一个初始容量为10的空列表但是JDK8中只是构造一个空的数组 ArrayList(Collection<? extends E> c)构造一个包含指定 collection 的元素的数组,这些元素是按.

双双博客 1071

浅谈JDK1.8中ArrayList的动态扩容

浅谈JDK1.8中ArrayList的动态扩容 简介 ArrayList的底层,实际就是一个可以动态扩容的Object数组,它继承了AbstractList这个抽象类,实现了List, RandomAccess, Cloneable, java.io.Serializable四个接口。其中,值得一提的是RandomAccess这个接口。RandomAccess是一个标记接口,用于标明实现该...

lxd_113的博客 2058

jdk1.8中的ArrayList底层数组扩容的方法

这篇文章将为大家详细讲解有关jdk1.8中的ArrayList底层数组扩容的方法,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。 一、结论先行 ArrayList在JDK1.8与JDK1.7底层区别 JDK1.7:ArrayList像饿汉式,直接创建一个初始容量为10的数组,当数组的长度不能容下所添加的内容时候,数组会扩容至原大小的1.5倍 JDK1.8:ArrayList像懒汉式,一开始创建一个长度为0的数组,当添加第一个元素时再创建一个始容量为10的数组,当数组

JavaPub 1095

JDK1.8ArrayList源码

JDK1.8ArrayList源码 数组是存储在内存中的一块逻辑上连续的内存,只有相同类型的数据才能放到数组中 构造方法 无参构造方法: 直接给elementData这个Object数组指向一个空数组. 带参构造方法: 如果参数大于0,就根据参数创建数组,参数为0则创建空数组,否则报错 带参构造方法: 将集合通过toArray()方法转换为数组传给当前的空的elementData数组,然...

fanfan999的博客 335

ArrayList jdk1.6 1.7 1.8

ArrayList(jdk1.6) /** * The array buffer into which the elements of the ArrayList are stored. * The capacity of the ArrayList is the length of this array buffer. */ private tran...

JavaSheng的专栏 1250

JDK 1.8ArrayList

JDK 1.8 ArrayList插入数据删除数据更改数据获取数据 插入数据 语法 数组名.add(数据); list.add("张三"); list.add(10); list.add(10.2); list.add('男'); 数组名.add(下标,数据); 根据下标在指定位置添加数据 //在第3位插入13 list.add(3,13); list.add(6,10); list.add(4,11); 第一个集合.addAll(第二个集合); 将第二个集合的数据添加在第一个集合的末

Cola_F的博客 287

【Java集合】ArrayList在JDK1.7与1.8中的区别

总结ArrayList在JDK1.7与1.8中的区别。

小七的博客 1761

JDK1.7与1.8中ArrayList源码分析

JDK1.7和1.8中ArrayList的源码分析

weixin_45949103的博客 515

基于JDK1.8 的ArrayList源码分析

基于JDK1.8 的ArrayList源码分析,代码注释。 JDK版本:jdk1.8.0_181

新新 854
上一篇: idea maven 打包 把依赖打上
下一篇: Java文件的路径分隔符
hwb_java
博客等级 码龄9年 0粉丝 3原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值