java arrayList 源码解读笔记

导入的函数式接口

import java.util.function.Consumer; // 函数式接口,给定一个参数,对其进行消费处理,处理方式可以是任何操作

例子(以下结果输出12,13),accept方法表示传入定义参数,andThen方法顺序执行处理方式:

public static void consumerExplame()
    {
        Consumer<Integer> consumer = x -> {
            int a = x + 2;
            System.out.println(a);
        };
        Consumer<Integer> consumer2 = x -> {
            int a = x + 3;
            System.out.println(a);
        };
        consumer.andThen(consumer2).accept(10);
    }

import java.util.function.Predicate;// 函数式接口,接收参数,根据这个参数进行一些处理,返回布尔结果

例子:

public static void predicateExplame()
    {
        // 过滤条件
        Predicate<Integer> predicate = x -> x > 7;
        System.out.println(predicate.test(10)); // 输出 true
        
        // 多个过滤条件与
        predicate = predicate.and(x -> x % 2 == 0);
        System.out.println(predicate.test(8)); // 输出 true
        
        // 多个条件过滤或
        predicate = predicate.or(x -> x < 3);
        System.out.println(predicate.test(1)); // 输出 true
        
        // 将过滤条件取反
        predicate = predicate.negate();
        System.out.println(predicate.test(5)); // 输出 true
        
        Predicate<String> predicate2 = Predicate.isEqual("test");
        System.out.println(predicate2.test("1"));// 输出false
        System.out.println(predicate2.test("test")); // 输出true
    }

import java.util.function.UnaryOperator;// 函数式接口,继承Function接口,接收一个泛型T对象,并且返回泛型T对象

例子:

public static void unaryOperatorExplame()
    {
        UnaryOperator<Integer> dda = x -> x + 1;
        System.out.println(dda.apply(1));// 2
        UnaryOperator<String> ddb = x -> x + 1;
        System.out.println(ddb.apply("aa"));// aa1
    }

操作计数:

父类AbstractList中定义protected transient int modCount = 0;记录集合的修改次数,每次变换都会加1,用于迭代器保持单线程唯一操作,如果出现了插入或者删除,就会被迭代器感知,进而抛出异常ConcurrentModificationException,ArrayList是非线程安全的。

/**
 * 数组为空的时候默认在扩容的时候默认赋予的数组长度
 */
private static final int DEFAULT_CAPACITY = 10;
/**
 * 空数组(1),无最小长度
 */
private static final Object[] EMPTY_ELEMENTDATA = {};
/**
 * 空数组(2),最小长度为10
 */
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
/**
 * 缓冲区数组
 */
transient Object[] elementData;
/**
 * 数组实际长度
 * @serial
 */
private int size;
/**
 * 构造函数,当参数大于0,按照该参数将缓冲区数组初始化,当参数等于0,将空数组(1)赋值给缓冲区数组,小于0抛出数字不合法异常
 *
 * @param  数组长度
 * @throws 数字不合法
 */
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);
    }
}
/**
 * 未传参数,给缓冲区数组赋值空数组(2)
 */
public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
/**
 * 构造函数,传参集合,将集合转成数组,并赋值给缓冲区数组,将数组长度赋值给实际长度,如果实际长度不等于0,
 * 判断数组的类型如果不等于Object类,用Arrays.copyOf将旧缓冲区数组中的元素一一转换成Object类,如果等于0,将空数组(1)赋值给缓冲区数组。
 * @param 集合
 * @throws 空指针异常
 */
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;
    }
}
/**
 * 操作计数加1,如果实际长度小于缓冲区数组长度,采用三元运算符,如果实际长度等于0的时候,给缓冲区赋值空数组(1),
 * 否则使用Arrays.copyOf赋值原缓冲区实际长度的值,主要用作arrayList动态增长的多余容量被删除了,例如分配了10个存储,
 * 只用了8个,还有2个为null进行去掉
 */
public void trimToSize() {
    modCount++;
    if (size < elementData.length) {
        elementData = (size == 0)
          ? EMPTY_ELEMENTDATA
          : Arrays.copyOf(elementData, size);
    }
}
/**
 * 确定数组的长度,用于预先知道数组长度或者大概长度,避免数组不断的扩容,参数传长度minCapacity,获取minExpand:
 * 如果缓冲区数组不等于空数组(2),minExpand=0,否则,minExpand=默认数组长度10。如果minCapacity >minExpand,
 * 调用方法ensureExplicitCapacity(minCapacity);,否则不做处理。该方法处理主要用作DEFAULTCAPACITY_EMPTY_ELEMENTDATA数组不能初始长度小于10
 *
 * @param   minCapacity   数组长度
 */
public void ensureCapacity(int minCapacity) {
    int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
        // any size if not default element table
        ? 0
        // larger than default for default empty table. It's already
        // supposed to be at default size.
        : DEFAULT_CAPACITY;

    if (minCapacity > minExpand) {
        ensureExplicitCapacity(minCapacity);
    }
}
/**
 * 如果缓冲区数组等于空数组(2),从默认长度10和minCapacity取最大值,调用方法ensureExplicitCapacity(minCapacity);
 * @param minCapacity 长度
 */
private void ensureCapacityInternal(int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
    }

    ensureExplicitCapacity(minCapacity);
}
/**
 * 操作计数加1,参数传长度minCapacity,如果minCapacity减去缓冲区数组的长度大于0,调用grow(minCapacity);对数组进行扩容。
 * @param minCapacity
 */
private void ensureExplicitCapacity(int minCapacity) {
    modCount++;

    // overflow-conscious code
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}

/**
 * 要分配数组的最大大小,一些虚拟机在数组中保存一些头字,分配更大的数组会报OutOfMemoryError错误,内存溢出。
 */
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

/**
 * 判断是否对数组进行扩容,获取缓冲区数组长度,并将缓冲区长度+缓冲区长度右移一位(除2),
 * 得到一个新的长度,如果新的长度小于传参长度,新长度等于传参长度,如果新长度大于MAX_ARRAY_SIZE最大长度,
 * 新长度newCapacity = hugeCapacity(minCapacity);,最后将缓冲区数组使用Arrays.copyOf按新的长度赋值给缓冲区数组。
 *
 * @param 数组长度
 */
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);
}

/**
 * 如果参数长度小于0,抛出内存溢出OutOfMemoryError错误,否则当参数长度大于最大数组大小,返回Integer.MAX_VALUE(某些虚拟机可能内存溢出),否则返回最大数组大小MAX_ARRAY_SIZE。
 * @param minCapacity 数组长度
 * @return
 */
private static int hugeCapacity(int minCapacity) {
    if (minCapacity < 0) // overflow
        throw new OutOfMemoryError();
    return (minCapacity > MAX_ARRAY_SIZE) ?
        Integer.MAX_VALUE :
        MAX_ARRAY_SIZE;
}

/**
 * 返回数组的长度。
 *
 * @return the number of elements in this list
 */
public int size() {
    return size;
}

/**
 * Returns 判断吧数组的长度是不是等于0.
 *
 * @return <tt>true</tt> if this list contains no elements
 */
public boolean isEmpty() {
    return size == 0;
}

/**
 * 调用indexOf(参数)方法判断是不是大于等于0.
 *
 * @param o element whose presence in this list is to be tested
 * @return <tt>true</tt> if this list contains the specified element
 */
public boolean contains(Object o) {
    return indexOf(o) >= 0;
}

/**
 * 如果参数为null,遍历循环实际长度,
 * 如果缓冲数组下标为当前迭代等于null的时候,返回当前下标,否则,遍历实际长度,
 * 如果参数等于缓冲区数组下标为当前迭代的值(equals判断),返回当前下标值,如果没有返回的时候,返回-1.
 */
public int indexOf(Object o) {
    if (o == null) {
        for (int i = 0; i < size; i++)
            if (elementData[i]==null)
                return i;
    } else {
        for (int i = 0; i < size; i++)
            if (o.equals(elementData[i]))
                return i;
    }
    return -1;
}

/**
 * 和上面类似,只不过返回的下标是最后一个
 */
public int lastIndexOf(Object o) {
    if (o == null) {
        for (int i = size-1; i >= 0; i--)
            if (elementData[i]==null)
                return i;
    } else {
        for (int i = size-1; i >= 0; i--)
            if (o.equals(elementData[i]))
                return i;
    }
    return -1;
}

/**
 * 调用父类的clone方法,将该数组结构拷贝,将缓冲区数组v.elementData调用Arrays.copyOf缓冲数组elementData,实际长度size,并将操作计数v.modCount设置为0,返回该数组v。
 *
 * @return a clone of this <tt>ArrayList</tt> instance
 */
public Object clone() {
    try {
        ArrayList<?> v = (ArrayList<?>) super.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值