简简单单复习一哈ArrayList和Arrays.asList()

红烧土豆泥
• 阅读 2484

1、面向对象补充(详见面试补充) 基于JDK11

静态代码块 > 非静态代码块 > 无参/有参构造

在同一次编译运行时,静态代码块只会被调用一次

List

ArrayList (数组,初始容量为10)

注:

除了通过 Iterator 自己的remove或add方法,迭代器将抛出ConcurrentModificationException 。 因此,面对并发修改,迭代器快速而干净地失败,而不是在未来不确定的时间冒着任意、非确定性行为的风险。

可被序列化,线程不安全

安全的List集合:

CopyOnWriteArrayList:官方解释意思大概为(由百度翻译)

ArrayList线程安全变体,其中所有可变操作( add 、 set等)都是通过制作底层数组的新副本来实现的。
这通常成本太高,但当遍历操作大大超过突变时可能比替代方法更有效,并且当您不能或不想同步遍历时很有用,但需要排除并发线程之间的干扰。 “快照”样式的迭代器方法使用对创建迭代器时数组状态的引用。 这个数组在迭代器的生命周期内永远不会改变,所以干扰是不可能的,并且迭代器保证不会抛出ConcurrentModificationException 。 自创建迭代器以来,迭代器不会反映对列表的添加、删除或更改。 不支持迭代器本身的元素更改操作( remove 、 set和add )。 这些方法抛出UnsupportedOperationException 。
允许所有元素,包括null 。
内存一致性影响:与其他并发集合一样,在将对象放入CopyOnWriteArrayList之前线程中的操作发生在另一个线程中从CopyOnWriteArrayList访问或删除该元素之后的操作之前。

Collections.synchronizedList(list);

ArrayList容量增加策略,>>1,右移一位除以2,即新容量在OldCapacity的基础上加OldCapacity的一半

/**
     * Returns a capacity at least as large as the given minimum capacity.
     * Returns the current capacity increased by 50% if that suffices.
     * Will not return a capacity greater than MAX_ARRAY_SIZE unless
     * the given minimum capacity is greater than MAX_ARRAY_SIZE.
     *
     * @param minCapacity the desired minimum capacity
     * @throws OutOfMemoryError if minCapacity is less than zero
     */
    private int newCapacity(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity <= 0) {
            if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
                return Math.max(DEFAULT_CAPACITY, minCapacity);
            if (minCapacity < 0) // overflow
                throw new OutOfMemoryError();
            return minCapacity;
        }
        return (newCapacity - MAX_ARRAY_SIZE <= 0)
            ? newCapacity
            : hugeCapacity(minCapacity);
    }

最大容量默认为Integer的最大值为2的31次方-1 -8

/**
     * The maximum size of array to allocate (unless necessary).
     * Some VMs reserve some header words in an array.
     * Attempts to allocate larger arrays may result in
     * OutOfMemoryError: Requested array size exceeds VM limit
     */
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

如果容量超过了这个值,则会使用Integer的最大值

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

List在对容量进行动态增加时,使用的是数组copy

Arrays.copyOf(elementData, size)
System.arraycopy(elementData, 0, a, 0, size);

补:数组Copy

Arrays.copyOf:

System.arraycopy:

LinkedList(链表 -> 双向链表)

注:

除了通过 Iterator 自己的remove或add方法,迭代器将抛出ConcurrentModificationException 。 因此,面对并发修改,迭代器快速而干净地失败,而不是在未来不确定的时间冒着任意、非确定性行为的风险。

Arrays

注意点:arrays.asList()

/**
 * 不能对Arrays.asList转换成的List进行remove或者add操作,否则会报一个异常
 * Exception in thread "main" java.lang.UnsupportedOperationException
 * 原因好像是因为Object的转换
 * 调用流程
 * @SafeVarargs
 *  @SuppressWarnings("varargs")
 *  public static <T> List<T> asList(T... a) {
 *      return new ArrayList<>(a);
 * }
 * ArrayList(E[] array) {
 *         a = Objects.requireNonNull(array);
 * }
 * public static <T> T requireNonNull(T obj) {
 *  if (obj == null)
 *      throw new NullPointerException();
 *  return obj;
 * }
 */
点赞
收藏
评论区
推荐文章
普通代码块 静态代码块 构造代码块......傻傻分不清
代码块的定义在Java中,使用括起来的代码被称为代码块。代码块的分类根据其位置和声明方式不同:面试题:构造块和静态块执行顺序在上面分类描述中,我们已经给出了答案;接下来我们跑一跑测试代码,根据代码执行结果来验证这些答案无继承关系javapackagecom.milo.java7.codeblock;/@authorMiloLee@d
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Wesley13 Wesley13
3年前
java实例化
初始化块实际上,初始化块是一个假象,使用javac命令编译java类后,初始化块会消失,初始化代码被还原到每个构造器中代码的最前面在实例化的过程中:前面的初始化块先执行,后面的后执行初始化块的修饰符只能是static普通初始化块负责对对象执行初始化,静态初始化块负责对类执行初始化初始化块只在创建
Wesley13 Wesley13
3年前
java试题复盘——9月8日
 上:1.可将语句块或方法设为同步使用的语句是(A) Asynchronized             用于方法或者代码块前,使此方法或者代码变成同步的 Bstatic                           用于声明静态变量 Cabstract                      用于定义抽象类或者方法 
Wesley13 Wesley13
3年前
jdk源码之Object的hashcode
packagejava.lang;publicclassObject{privatestaticnativevoidregisterNatives();//创建对象时,先调用静态代码块(即registerNatives()方法),。native关键字表示该方法不是由java语言编写,
Wesley13 Wesley13
3年前
Java中静态代码块、构造代码块、构造函数、普通代码块
转载来源http://www.cnblogs.com/ysocean/(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fwww.cnblogs.com%2Fysocean%2F)1、静态代码块①、格式  在java类中(方法中不能存在静态代码块)使用s
Wesley13 Wesley13
3年前
Java中类的加载顺序剖析(常用于面试题)
如果类A和类B中有静态变量,静态语句块,非静态变量,非静态语句块,构造函数,静态方法,非静态方法,同时类A继承类B,请问当实例化A时,类内部的加载顺序是什么?Demo:ClassB:publicclassB{//静态变量staticinti1;//静态语句块static{
Wesley13 Wesley13
3年前
Java提高篇——静态代码块、构造代码块、构造函数以及Java类初始化顺序
静态代码块:用staitc声明,jvm加载类时执行,仅执行一次构造代码块:类中直接用{}定义,每一次创建对象时执行。执行顺序优先级:静态块,main(),构造块,构造方法。构造函数publicHelloA(){//构造函数}关于构造函数,以下几点要注意:1.对象一建立,就会调用与之相应的构造
Wesley13 Wesley13
3年前
Java类的初始化顺序 (静态变量、静态初始化块、变量、初始...
大家在去参加面试的时候,经常会遇到这样的考题:给你两个类的代码,它们之间是继承的关系,每个类里只有构造器方法和一些变量,构造器里可能还有一段代码对变量值进行了某种运算,另外还有一些将变量值输出到控制台的代码,然后让我们判断输出的结果。这实际上是在考查我们对于继承情况下类的初始化顺序的了解。我们大家都知道,对于静态变量、静态初始化块、变量、初始化块
京东云开发者 京东云开发者
7个月前
无用代码扫描组件设计
1、现状痛点系统越来越臃肿,开发过程中可能产生的无用代码增加了系统维护成本。2、设计思路2.1、静态代码扫描方案本方案解决静态代码下无调用方法扫描,通过ASTParser对静态文件进行扫描分析,获取代码块来判断调用关系。基本步骤及思路(1)载入本地磁盘项目