FastList和Arraylist的区别

1.引言

FastList是一个List接口的精简实现,只实现了接口中必要的几个方法。
JDK ArrayList每次调用get()方法时都会进行rangeCheck检查索引是否越界,FastList的实现中去除了这一检查,只要保证索引合法那么rangeCheck就成为了不必要的计算开销(当然开销极小)。此外,HikariCP使用List来保存打开的Statement,当Statement关闭或Connection关闭时需要将对应的Statement从List中移除。通常情况下,同一个Connection创建了多个Statement时,后打开的Statement会先关闭。ArrayList的remove(Object)方法是从头开始遍历数组,而FastList是从数组的尾部开始遍历,因此更为高效。

简而言之就是 自定义数组类型(FastList)代替ArrayList:避免每次get()调用都要进行range check,避免调用remove()时的从头到尾的扫描

2.源码展示

ArrayList 的get() 方法
每次都要执行rangeCheck() 方法

  /**
     * Returns the element at the specified position in this list.
     *
     * @param  index index of the element to return
     * @return the element at the specified position in this list
     * @throws IndexOutOfBoundsException {@inheritDoc}
     */
    public E get(int index) {
        rangeCheck(index);

        return elementData(index);
    }


  /**
     * Checks if the given index is in range.  If not, throws an appropriate
     * runtime exception.  This method does *not* check if the index is
     * negative: It is always used immediately prior to an array access,
     * which throws an ArrayIndexOutOfBoundsException if index is negative.
     */
    private void rangeCheck(int index) {
        if (index >= size)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }

然后是FastList的get()方法
是不是少了一个步骤

  /**
    * Get the element at the specified index.
    *
    * @param index the index of the element to get
    * @return the element, or ArrayIndexOutOfBounds is thrown if the index is invalid
    */
   @Override
   public T get(int index)
   {
      return elementData[index];
   }

还有就是它们的删除操作
ArrayList:

 /**
     * Removes the element at the specified position in this list.
     * Shifts any subsequent elements to the left (subtracts one from their
     * indices).
     *
     * @param index the index of the element to be removed
     * @return the element that was removed from the list
     * @throws IndexOutOfBoundsException {@inheritDoc}
     */
    public E remove(int index) {
        rangeCheck(index);

        modCount++;
        E oldValue = elementData(index);

        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

        return oldValue;
    }

FastList:

/**
    * This remove method is most efficient when the element being removed
    * is the last element.  Equality is identity based, not equals() based.
    * Only the first matching element is removed.
    *
    * @param element the element to remove
    */
   @Override
   public boolean remove(Object element)
   {
      for (int index = size - 1; index >= 0; index--) {
         if (element == elementData[index]) {
            final int numMoved = size - index - 1;
            if (numMoved > 0) {
               System.arraycopy(elementData, index + 1, elementData, index, numMoved);
            }
            elementData[--size] = null;
            return true;
         }
      }

      return false;
   }

3. 代码演示

FastList 位于com.zaxxer.hikari.util.FastList;包下

创建方式跟ArrayList 差不多
user 是我创建的实体类型
同时也支持lambda表达式

List<User> list=new FastList<>(User.class);
list= list.stream().sorted(Comparator.comparing(User::getId).reversed()).collect(Collectors.toList());

4.我的参考

http://cmsblogs.com/?p=2518
十分感谢这位大哥,本来我是在查看 spring boot2.0 自带数据源时,无意间看到了,觉得不错分享给大家。
此list不支持lambda表达式
本人还是java小白,如果有什么不对的请在下方留言。

相关连接:

csdn博客地址:https://blog.youkuaiyun.com/JYTXIOABAI

个人qq: 1165892587

<think>首先,用户的问题是:“我想理解Java中ListArrayList区别 请问Java ListArrayList之间的区别”。我需要基于提供的引用系统指令来回答。 系统指令: - 所有行内数学表达式必须使用$...$格式。 - 独立公式必须使用$$...$$格式并单独成段。 - 使用LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识。 - 回答结构清晰,帮助用户逐步解决问题。 - 保证回答真实可靠。 参考的引用: - [^1]: 解释了List是一个接口,ArrayList是List接口的一个实现类。List不能被实例化,但可以创建一个指向自己的对象引用,使用ArrayList实现。 - [^2]: 关于List转ArrayList的转换。 - [^3]: 类似[^1],强调List是接口,ArrayList是具体类,实例化方式不同。 - [^4]: 描述了ArrayList的使用,包括底层实现示例代码。 - [^5]: 详细说明了ListArrayList区别,包括实例化错误正确方式。 用户的问题是关于Java中ListArrayList区别。我需要从引用中提取关键点,并组织成清晰的回答。 关键区别: 1. **定义类型**: - List是一个接口(interface),定义了一组方法(如add, remove, get等)。 - ArrayList是List接口的一个具体实现类(class),实现了List接口的所有方法。 2. **实例化**: - List不能被直接实例化,因为接口不能被构造。尝试`List list = new List();`会导致编译错误。 - ArrayList可以被实例化,因为它是类。`ArrayList list = new ArrayList();`是正确的。 - 常见做法是使用接口引用:`List list = new ArrayList();`。这允许使用多态,方便切换到其他List实现(如LinkedList)。 3. **使用区别**: - 当使用`List list = new ArrayList();`时,只能调用List接口中定义的方法,不能调用ArrayList特有的方法(如果有)。 - 当使用`ArrayList list = new ArrayList();`时,可以调用ArrayList的所有方法,包括那些不在List接口中的方法。 4. **灵活性多态**: - 使用List接口引用提供灵活性。如果需要更改实现类(如从ArrayList到LinkedList),只需修改实例化部分,而不影响代码其他部分。 - 直接使用ArrayList引用则绑定到特定实现。 5. **其他实现**: - List接口有其他实现类,如LinkedList、Vector等。ArrayList是其中之一,基于数组实现。 从引用中: - [^1] 说:List是接口,ArrayList是List接口的实现类。List不能被构造,但可以创建指向自己的对象引用,如`List list = new ArrayList();`。 - [^3] 说:List定义是接口,ArrayList是具体类。实例化方式:`List list2 = new ArrayList();`正确,`ArrayList list3 = new ArrayList();`也正确。 - [^5] 强调:List接口不能被构造,`List list = new List();`错误,`List list = new ArrayList();`正确。 回答结构: 1. **逐步解释**:先介绍ListArrayList的概念,然后解释区别。 2. **清晰结构**:使用标题或列表来组织。 3. **添加引用**:在相关段落末尾添加引用标识。 4. **生成相关问题**:在最后添加相关问题部分。 5. **使用中文**:整个回答用中文。 6. **数学表达式**:用户问题中没有数学内容,但如果有,需用$...$或$$...$$格式。这里可能不需要,除非涉及算法等。 回答大纲: - 引言:简要介绍问题。 - 区别点: - 定义:List是接口,ArrayList是实现类。 - 实例化:为什么List不能直接实例化。 - 使用方式:接口引用的好处。 - 示例代码。 - 总结。 - 相关问题。 相关问题生成: 基于主题,如: 1. Java中List接口的其他实现类是什么? 2. 如何选择ArrayListLinkedList? 3. ArrayListVector的区别? 4. 在多线程环境中使用List的注意事项? 5. List接口的常用方法有哪些? 最终回答: - 确保引用自然添加,例如在解释点后添加[^1]等。</think>### Java中ListArrayList区别Java中,`List``ArrayList`是集合框架的核心部分,但它们有本质区别。让我一步步解释它们的定义、关系使用场景,确保回答清晰可靠。 #### 1. **定义类型区别** - **`List`是一个接口(interface)**:它定义了集合的基本操作规范,如添加、删除、遍历元素等。接口不能被直接实例化,只能被实现。例如,`List`声明了`add()`, `remove()`, `get()`等方法,但没有具体实现[^1]。 - **`ArrayList`是一个具体类(class)**:它是`List`接口的实现类之一,基于动态数组实现。`ArrayList`提供了`List`接口中所有方法的具体实现,并添加了自身的方法(如`trimToSize()`)。底层是一段连续空间,支持动态扩容,适合随机访问[^4]。 - **关键点**:`List`是抽象规范,`ArrayList`是具体实现。类似于“蓝图”“建筑”的关系[^3]。 #### 2. **实例化方式区别** - **`List`不能直接实例化**:因为接口不能被构造。尝试`List list = new List();`会导致编译错误,因为Java不允许实例化接口[^1][^5]。 - **`ArrayList`可以直接实例化**:作为类,它可以被直接创建对象。例如: ```java ArrayList<String> arrayList = new ArrayList<>(); // 正确 ``` - **常见做法:使用接口引用**:推荐`List list = new ArrayList();`。这创建了一个`ArrayList`对象,但引用类型为`List`接口,限制了只能调用`List`接口中的方法[^1][^3]。例如: ```java List<String> list = new ArrayList<>(); // 正确 list.add("Java"); // 调用List接口的add方法 // list.trimToSize(); // 错误:不能调用ArrayList特有方法 ``` #### 3. **使用区别灵活性** - **方法访问范围**: - 使用`List list = new ArrayList();`时,只能访问`List`接口定义的方法(如`add()`, `get()`),不能调用`ArrayList`特有方法(如`ensureCapacity()`)。这确保了代码与具体实现解耦[^3][^5]。 - 使用`ArrayList list = new ArrayList();`时,可以访问`ArrayList`的所有方法,包括特有方法,但代码灵活性降低。 - **多态可扩展性**:使用`List`接口引用允许轻松切换实现类。例如,如果需要从`ArrayList`改为`LinkedList`,只需修改实例化代码: ```java List<String> list = new LinkedList<>(); // 只需改这一行 ``` 其他使用`list`的代码无需变更。这符合面向接口编程原则,提升代码维护性[^1][^3]。 - **性能考量**:`ArrayList`基于数组,随机访问快(时间复杂度$O(1)$),但插入/删除元素慢(平均$O(n)$);而`LinkedList`基于链表,插入/删除快,但访问慢。选择`List`接口引用时,可根据需求切换实现[^4]。 #### 4. **示例代码对比** 以下代码展示正确错误的实例化方式: ```java // 错误:List是接口,不能实例化 // List<String> errorList = new List<>(); // 正确:使用ArrayList实现List接口 List<String> list1 = new ArrayList<>(); // 只能调用List接口方法 list1.add("Hello"); System.out.println(list1.get(0)); // 输出 "Hello" // 正确:直接使用ArrayListArrayList<String> list2 = new ArrayList<>(); list2.add("World"); list2.trimToSize(); // 可调用ArrayList特有方法 ``` #### 总结 - **核心区别**:`List`是接口,定义规范;`ArrayList`是实现类,提供具体功能。实例化时,`List`必须通过实现类(如`ArrayList`)创建对象引用[^1][^5]。 - **最佳实践**:优先使用`List list = new ArrayList();`以保持代码灵活性可扩展性。仅在需要`ArrayList`特有方法时,才直接使用`ArrayList`引用[^3][^5]。 通过以上解释,您应该能清晰理解两者的区别。如果有具体代码场景,我可以进一步分析! ### 相关问题 1. Java中`List`接口的其他实现类(如`LinkedList`或`Vector`)有哪些,如何选择? 2. `ArrayList``Vector`在Java中有什么区别,特别是在多线程环境下? 3. 如何优化`ArrayList`的性能,比如处理大量数据时的动态扩容机制? 4. Java集合框架中,`List`接口的常用方法有哪些,如何高效遍历元素? 5. 为什么在面向对象编程中推荐使用接口(如`List`)而非具体类(如`ArrayList`)?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值