你也應該處理你的收藏。
1-如果您事先知道您的名單會很大,您可以使用ArrayList Capacity
。
默認情況下,ArrayList的初始容量爲10條記錄。當你的列表增長時,java會連續(小)地重新分配列表,從而失去很多時間。如果你這樣做,例如
List<HashMap<String,String>> userData=new ArrayList<HashMap<String,String>>(500);
你將有一個initialCapacity 500,節省大量的重新分配,所以時間。
此外,方法ensureCapacity
可以讓您的列表增加用戶定義的容量,這可能很有用。
因此,如果您事先知道結果的大小,或者至少您有一個想法,那麼您可以使用它。否則,如果之後只需要迭代列表中的內容,則可以考慮LinkedList
,它具有恆定的添加操作時間(但不適用於位置訪問)。
2-也考慮到你的行數據結構,創建一個封裝你的結果集列的對象,而不是每一行的地圖(所以非常大量的地圖,每一個都需要一定的內存分配,所以資源和時間)將更加高效。
看一看在CollectionFramework,在ArrayList和LinkedList文檔
UPDATE 這裏是一些 '骯髒' 基準測試
package com.test;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
public class LoopTest {
public static void main(String[] args) {
LoopTest lt=new LoopTest();
int records = 200000;
lt.execute(records, false);
lt.execute(records, true);
lt.executeObj(records, false);
lt.executeObj(records, true);
lt.executeReflect(records, false);
lt.executeReflect(records, true);
}
public void execute(int loops, boolean useCapacity){
Date start=new Date();
System.out.println("EXAMPLE WITH HASHMAP");
System.out.println(start+ " time: "+start.getTime()+" Start for loops="+loops+ " and useCapacity="+useCapacity);
List<HashMap<String,String>> userData=null;
if(useCapacity)
userData=new ArrayList<HashMap<String,String>>(loops);
else
userData=new ArrayList<HashMap<String,String>>();
for(int i=0;i<loops;i++){
HashMap<String,String> recordMap = new HashMap<String,String>();
for (int j = 1; j <= 10; j++) {
String key = j+"";
String value = j+" val";
recordMap.put(key, value);
}
userData.add(recordMap);
}
Date end=new Date();
System.out.println(end+ " time: "+end.getTime()+", elapsed="+(end.getTime()-start.getTime())+" end for loops="+loops+ " and useCapacity="+useCapacity);
System.out.println("-------------------------");
}
public void executeObj(int loops, boolean useCapacity){
System.out.println("EXAMPLE WITH CLASSIC OBJECT");
Date start=new Date();
System.out.println(start+ " time: "+start.getTime()+" Start for loops="+loops+ ", object and useCapacity="+useCapacity);
List<TestObj> userData=null;
if(useCapacity)
userData=new ArrayList<TestObj>(loops);
else
userData=new ArrayList<TestObj>();
for (int i=0;i<loops;i++){
TestObj testObj = new TestObj();
testObj.test1="1";
testObj.test2="1";
testObj.test3="1";
testObj.test4="1";
testObj.test5="1";
testObj.test6="1";
testObj.test7="1";
testObj.test8="1";
testObj.test9="1";
testObj.test10="1";
testObj.test11="1";
testObj.test12="1";
testObj.test13="1";
testObj.test14="1";
testObj.test15="1";
testObj.test16="1";
testObj.test17="1";
testObj.test18="1";
testObj.test19="1";
testObj.test20="1";
userData.add(testObj);
}
Date end=new Date();
System.out.println(end+ " time: "+end.getTime()+", elapsed="+(end.getTime()-start.getTime())+" end for loops="+loops+ ", object and useCapacity="+useCapacity);
System.out.println("-------------------------");
}
public void executeReflect(int loops, boolean useCapacity){
System.out.println("EXAMPLE WITH REFLECTION");
Date start=new Date();
System.out.println(start+ " time: "+start.getTime()+" Start for loops="+loops+ ", object and useCapacity="+useCapacity);
List<TestObj> userData=null;
if(useCapacity)
userData=new ArrayList<TestObj>(loops);
else
userData=new ArrayList<TestObj>();
for (int i=0;i<loops;i++){
try{
Class<?> objClass=Class.forName("com.test.TestObj");
Object myObj=objClass.newInstance();
for(int j=1;j<=20;j++){
Field f=objClass.getDeclaredField("test"+j);
f.set(myObj, "1");
}
userData.add((TestObj)myObj);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Date end=new Date();
System.out.println(end+ " time: "+end.getTime()+", elapsed="+(end.getTime()-start.getTime())+" end for loops="+loops+ ", reflect and useCapacity="+useCapacity);
System.out.println("-------------------------");
}
}
TestObj是包含一個名爲只有公共領域的對象test1的... test25 。爲了簡單和快速,我將它們公諸於世,在現實世界中,您會讓它們變得私密。它可以被更多的工程,但我心中已經迅速地完成它..
這裏闡述
EXAMPLE WITH HASHMAP, useCapacity=false, loops=200000
Wed Feb 15 06:04:48 CET 2017 time: 1487135088903 Start for loops=200000 and useCapacity=false
Wed Feb 15 06:04:55 CET 2017 time: 1487135095922, elapsed=7019 end for loops=200000 and useCapacity=false
-------------------------
EXAMPLE WITH HASHMAP, useCapacity=true, loops=200000
Wed Feb 15 06:04:55 CET 2017 time: 1487135095922 Start for loops=200000 and useCapacity=true
Wed Feb 15 06:05:01 CET 2017 time: 1487135101073, elapsed=5151 end for loops=200000 and useCapacity=true
-------------------------
EXAMPLE WITH CLASSIC OBJECT, useCapacity=false, loops=200000
Wed Feb 15 06:05:01 CET 2017 time: 1487135101073 Start for loops=200000, object and useCapacity=false
Wed Feb 15 06:05:01 CET 2017 time: 1487135101254, elapsed=181 end for loops=200000, object and useCapacity=false
-------------------------
EXAMPLE WITH CLASSIC OBJECT, useCapacity=true, loops=200000
Wed Feb 15 06:05:01 CET 2017 time: 1487135101254 Start for loops=200000, object and useCapacity=true
Wed Feb 15 06:05:01 CET 2017 time: 1487135101274, elapsed=20 end for loops=200000, object and useCapacity=true
-------------------------
EXAMPLE WITH REFLECTION, useCapacity=false, loops=200000
Wed Feb 15 06:05:01 CET 2017 time: 1487135101274 Start for loops=200000, object and useCapacity=false
Wed Feb 15 06:05:05 CET 2017 time: 1487135105562, elapsed=4288 end for loops=200000, reflect and useCapacity=false
-------------------------
EXAMPLE WITH REFLECTION, useCapacity=true, loops=200000
Wed Feb 15 06:05:05 CET 2017 time: 1487135105562 Start for loops=200000, object and useCapacity=true
Wed Feb 15 06:05:09 CET 2017 time: 1487135109711, elapsed=4149 end for loops=200000, reflect and useCapacity=true
-------------------------
的輸出正如您將看到使用量帶來約7秒至5.1秒HashMap的例子。
以傳統方式使用對象,使用陣列中的容量可以達到181毫秒(!)甚至20毫秒(!!)。
由於使用容量(4288 vs 4149),反射性能大約在4秒左右。
請注意,基準測試的確切時間因執行而異。但總的來說,時間順序總是一樣的。
關於在'塊'中獲取記錄是內存一致性的一個很好的解決方案,特別是如果您的闡述可能很長時間的話。經常長時間運行的查詢可能會出現「快照太舊」的錯誤,這可能會產生問題。而且它也不確定性能會如何降低。 在過去,我必須處理類似的問題,一個非常好的解決方案是在源表中放置一個帶有索引的字段「chunk_id」,這樣可以輕鬆地重複查詢下一行的查詢,並給我比檢索表格的所有內容更有效率。一般來說,你只需要一種方法來識別來自組1,組2,......組n的記錄組(當然在那裏放置索引)
PS反射的例子很簡單,但它是隻是爲了演示如何操作,你可以使用很多功能,包括方法等
如果將所有200000行保存在列表中,它將會是內存密集型的。你對數據做了什麼?它不可能是'SELECT'按您需要的格式輸入 –
@ScaryWombat號我需要根據每條記錄做一些處理,如果在列表中添加所有行都是內存密集的,建議保持結果集打開很長時間,直到我處理所有記錄? –
即使我說'記憶密集型',這對你來說可能不是問題。 g有什麼問題? –