Java小白踩坑錄 - 數組 & List

別人家的孩子爲什麼總是很厲害?--Java數組和List

Java 家族中的別人家的孩子–數組

小白一直以爲數組和 ArrayList 是一樣的,因爲 ArrayList 的內部結構就是數組,那爲什麼數組就成爲別人家的孩子呢,讓我們看一下吧:

import java.util.ArrayList;
import java.util.List;
public class TestArray {
	private static final int batch = 10_000;
	public static void main(String[] args) {
		long start = System.currentTimeMillis();
		insert2Array();
		long end = System.currentTimeMillis();
		System.out.println(end-start);
		insert2List();
		System.out.println(System.currentTimeMillis()-end);		
	}
	
	static void insert2Array() {
		int[] nums = new int[batch];
		for(int i = 0;i < batch;i++) {
			nums[i]=i;
		}
	}
	
	static void insert2List() {
		List<Integer> nums=new ArrayList<Integer>();
		for(int i=0;i<batch;i++) {
			nums.add(i);
		}
      }
}

數量級 batch 不同,耗時不同:

batch 數組耗時 Arraylist 耗時(單位毫秒)
1w 0 1
10w 1 4
100w 3 18
1kw 18 196
10kw 153 21880

別人家的孩子爲什麼這麼優秀?

因爲我們在拿自己孩子的缺點,給別人家的孩子的優點進行比較,看看代碼:

List<Integer> nums=new ArrayList<Integer>();
// ...
nums.add(i);

其中,nums.add (i); 暗含玄機。

因 List 只能存放 Integer 對象型的變量,i 需要先轉爲 Integer,然後才能插入,就是這個動作影響了主要性能,我們可以驗證一下這個問題。

類型同爲 String:

public class TestArray2 {
	private static final int batch = 10_000;
	public static void main(String[] args) {
		long start=System.currentTimeMillis();
		insert2Array();
		long end=System.currentTimeMillis();
		System.out.println(end-start);
		insert2List();
		System.out.println(System.currentTimeMillis()-end);		
	}
	
	static void insert2Array() {
		String[] nums = new String[batch];
		for(int i=0;i<batch;i++) {
			nums[i]=""+i;
		}
	}
	
	static void insert2List() {
		List<String> nums=new ArrayList<String>();
		for(int i=0;i<batch;i++) {
			nums.add(""+i);
		}
	}
}

batch 數組耗時 Arraylist 耗時

發現自家孩子的優勢了吧!

總結

Java 語言設計的數據結構如 set、list、map 等只能存放引用對象,碰到數值型的問題時,就會發生拆箱、裝箱的動作,特別是數據較大時,拆箱、裝箱對性能的影響就比較大了,所以寫程序時或者設計時需要根據場景選擇合適的數據結構。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章