java性能优化读书笔记之三《程序优化===集合优化(list)》

说明:本文内容是针对于java集合的性能优化

1. 数据结构

请参考博客数据结构

2. List接口

概述

List是java重要结构之一, 它们的类图如下:
这里写图片描述

ArrayList和Vector是基于数组数据机构实现的。内部的操作都是对数组进行插入、删除,修改,遍历。可以说ArrayList和Vector是一个可扩容的动态数组。ArrayList与Vector不同之处在于Vector是线程安全的。

LinkList是基于双向链表数据结构实现的。内部的操作是对链表的节点(node)进行插入、删除、修改遍历。

结构图(数组)
这里写图片描述
结构图(链表)
这里写图片描述

3. 使用场景

LinkList在元素添加、删除效率比arrayList高,arrayList删除的元素越靠前,效率越低。
arryList在元素查询比LinkList高

4. 源码分析

无参的构造函数
代码清单:

    /**
     * Constructs an empty list with the specified initial capacity.
     *
     * @param   initialCapacity   the initial capacity of the list
     * @exception IllegalArgumentException if the specified initial capacity
     *            is negative
     */
    public ArrayList(int initialCapacity) {
    super();
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
    this.elementData = new Object[initialCapacity];
    }

    /**
     * Constructs an empty list with an initial capacity of ten.
     */
    public ArrayList() {
    this(10);
    }

从源码中获悉,arrayList默认的初始化容器大小为10。

add方法
代码清单

  /**
     * Appends the specified element to the end of this list.
     *
     * @param e element to be appended to this list
     * @return <tt>true</tt> (as specified by {@link Collection#add})
     */
    public boolean add(E e) {
    //调用此方法,判断容器是否需要扩容
    ensureCapacity(size + 1);  // Increments modCount!!
    //新元素赋值到指定的位置(size++)
    elementData[size++] = e;
    return true;
    }


 /**
     * Increases the capacity of this <tt>ArrayList</tt> instance, if
     * necessary, to ensure that it can hold at least the number of elements
     * specified by the minimum capacity argument.
     *
     * @param   minCapacity   the desired minimum capacity
     */
    public void ensureCapacity(int minCapacity) {
    modCount++;
    //获取容器的容量
    int oldCapacity = elementData.length;
    //判断容器所需的最小容量是否大于本身的容器大小
    if (minCapacity > oldCapacity) {
        Object oldData[] = elementData;
        //容器扩容后的容量
        int newCapacity = (oldCapacity * 3)/2 + 1;
            //容器扩容后的容量小于容器所需的最小容量。则使用容器所需的最小容量。反之不需要
            if (newCapacity < minCapacity)
        newCapacity = minCapacity;
            // minCapacity is usually close to size, so this is a win:
            //数组复制(之后的调用,大家自己看)
            elementData = Arrays.copyOf(elementData, newCapacity);
    }
    }

从源码中获取当容器所需的最小容量大于本身的容器大小。需要进行容器容量扩容。扩容的大小计算法则为(oldCapacity * 3)/2 + 1

linkList就不讲了

5. List优化点

  1. list容器在添加、删除频繁操作时,请使用linkList。list容器在遍历元素频繁操作时,请使用arrayList。具体场景具体分析
  2. 在特定的场景清楚list容器的容量,自己给定list容器的容量。不要使用默认的容器的容量(默认的大小为10)。这样做好处在于避免由于默认的容器容量比较小。导致list容器的容量频繁的扩容。(一般减少代码的运行,就能提高程序性能)

arrayList和linkList性能比较

package org.com.program.data;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/**
 * arrayList 添加的性能低于linkedList(在一定数据量),指定arrayList容量,添加的性能高于linkedList
 * arrayList 查询的效率大幅度高于linkedList
 * arrayList 删除元素越靠前,效率越低。linkedList没有变化
 * @author Administrator
 *
 */

public class List01 {
    private List<Object> arrayList = null;
    private List<Object> linkedList = null;
    private long startTime;
    private long endTime;

    @Before
    public void listAdd() {
        arrayList = new ArrayList<Object>();

        //#######arrayList 与linkedList添加功能性能比较
        startTime = System.currentTimeMillis();
        for(int i=0; i<5000000; i++) {
            arrayList.add(i);
        }

        endTime = System.currentTimeMillis();
        System.out.println("arrayList to add  time{}:"+(endTime-startTime));


        linkedList = new LinkedList<Object>();

        startTime = System.currentTimeMillis();
        for(int i=0; i<5000000; i++) {
            linkedList.add(i);
        }

        endTime = System.currentTimeMillis();
        System.out.println("linkedList to add time{}:"+(endTime-startTime));
    }

    @Test
    public void listQuery() {

        //#######arrayList 与linkedList查询功能性能比较
        startTime = System.currentTimeMillis();
        for(int i=0; i<50000; i++) {
            arrayList.get(i);
        }
        endTime = System.currentTimeMillis();
        System.out.println("arrayList to query time{}:"+(endTime-startTime));



        //#######arrayList 与linkedList查询功能性能比较
        startTime = System.currentTimeMillis();
        for(int i=0; i<50000; i++) {
            linkedList.get(i);
        }
        endTime = System.currentTimeMillis();
        System.out.println("linkedList to query time{}:"+(endTime-startTime));

    }

    @After
    public void listDel() {


        //#######arrayList 与linkedList删除功能性能比较
        startTime = System.currentTimeMillis();
        arrayList.remove(0);

        endTime = System.currentTimeMillis();
        System.out.println("arrayList to del  time{}:"+(endTime-startTime));


        startTime = System.currentTimeMillis();

        linkedList.remove(0);

        endTime = System.currentTimeMillis();
        System.out.println("linkedList to del time{}:"+(endTime-startTime));
    }   
}

arrayList和linkList性能比较===》性能结果
这里写图片描述

给定arrayList容量大小与默认的arrayList容器大小性能比较

package org.com.program.data;

import java.util.ArrayList;
import java.util.List;

import org.junit.Test;
/**
 * 给定arrayList容量大小与默认的arrayList容器容量大小性能比较
 * @author Administrator
 *
 */

public class List03 {

    private List<Object> arrayList = null;
    private long startTime =0L;
    private long endTime = 0L;

    //默认arrayList容器容量(10)
    @Test
    public void defaultCapacity() {
        arrayList = new ArrayList<Object>();

        startTime = System.currentTimeMillis();
        for(int i=0; i<5000000; i++) {
            arrayList.add(i);
        }

        endTime = System.currentTimeMillis();
        System.out.println("arryList default capacity to add time{}:"+(endTime-startTime));
    }


    //指定arrayList容器容量(5000000)
    @Test
    public void specifiedCapacity() {
        arrayList = new ArrayList<Object>(5000000);

        startTime = System.currentTimeMillis();
        for(int i=0; i<5000000; i++) {
            arrayList.add(i);
        }

        endTime = System.currentTimeMillis();
        System.out.println("arryList specified capacity to add time{}:"+(endTime-startTime));
    }
}

给定arrayList容量大小与默认的arrayList容器大小性能结果
这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值