Java優(yōu)化for循環(huán)嵌套的高效率方法
前幾天有人問過我一個問題,就是兩個嵌套for循環(huán)執(zhí)行效率的問題,問有什么好的辦法替換。當時我想了想,實在想不起來,哎,慚愧?。?! 請教了答案,恍然大悟。
比如:兩個list中分別裝有相同的對象數(shù)據(jù)。 list1中有3萬條對象數(shù)據(jù)。 list2中有2萬條對象數(shù)據(jù)(但是對象中的某個屬性變量為空)。兩個list中的id或者其他變量都一模一樣。請用最快的方式找出list2中變量為空的那個對象,并且去list1中找出id相同的對象。 或者可以理解成,從list2中找出變量為空的,去list1中找出對應(yīng)的對象,然后把為空的列補上。總之就是這么一個意思,先 for 循環(huán) list2,判斷一下每個對象的那個屬性變量是否為空,如果為空,再去for循環(huán)list1,找出id一樣的對象,就算執(zhí)行成功了。
那么請看下邊的for循環(huán)嵌套的解決方式:
for(Member m2:list2){ if(m2.getName()==null){ for(Member m1:list1){ if(m1.getId().intValue()==m2.getId().intValue()){ System.out.println(m2.getId()+" Name 值為空!!!"); } } } }
這樣真的好嗎? 如果有上萬,甚至十幾萬的數(shù)據(jù),那么這個執(zhí)行效率問題,我就不多說了。 非常非常的慢。
下邊來看使用map代替的執(zhí)行方式,以及兩種方式的效率對比:
import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; class Member { private Integer id; private String name; private Integer age; private Date addDate; public Member() { } public Member(Integer id, String name, Integer age, Date addDate) { super(); this.id = id; this.name = name; this.age = age; this.addDate = addDate; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Date getAddDate() { return addDate; } public void setAddDate(Date addDate) { this.addDate = addDate; } } public class For2 { public static void main(String[] args) throws InterruptedException { List<Member> list1 = new ArrayList<>(); List<Member> list2 = new ArrayList<>(); for(int i=0;i<30000;i++){ Date date = new Date(); list1.add(new Member((i+1),"技術(shù)客",(i+1), date)); if(i%2==0){ list2.add(new Member((i+1),null,(i+1), date)); } } //雙for循環(huán)嵌套測試 long s1 = System.currentTimeMillis(); int forNumber = 0; for(Member m2:list2){ if(m2.getName()==null){ for(Member m1:list1){ if(m1.getId().intValue()==m2.getId().intValue()){ // System.out.println(m2.getId()+" Name 值為空!!!"); forNumber++; } } } } long s2 = System.currentTimeMillis(); System.out.println("雙for循環(huán)查詢時間為:"+(s2-s1)+"(毫秒),一共查詢出"+forNumber+"條數(shù)據(jù) \n\n\n"); TimeUnit.SECONDS.sleep(3); //map查詢測試 long s3 = System.currentTimeMillis(); int mapNumber = 0; Map<Integer, Member> map = new HashMap<>(); for(Member m1:list1){ map.put(m1.getId(), m1); } for(Member m2:list2){ if(m2.getName()==null){ Member m = map.get(m2.getId()); if(m!=null){ // System.out.println(m2.getId()+" Name 值為空!!!"); mapNumber++; } } } long s4 = System.currentTimeMillis(); System.out.println("使用map結(jié)構(gòu)查詢時間為:"+(s4-s3)+"(毫秒),一共查詢出"+mapNumber+"條數(shù)據(jù) \n\n\n"); } }
輸出結(jié)果:
雙for循環(huán)查詢時間為:1578(毫秒),一共查詢出15000條數(shù)據(jù)
使用map結(jié)構(gòu)查詢時間為:14(毫秒),一共查詢出15000條數(shù)據(jù)
如果我們模擬10萬條數(shù)據(jù),然后其中五千條重復數(shù)據(jù)的情況下:效率更是天壤之別。
看輸出結(jié)果:
雙for循環(huán)查詢時間為:30929(毫秒),一共查詢出50000條數(shù)據(jù)
使用map結(jié)構(gòu)查詢時間為:24(毫秒),一共查詢出50000條數(shù)據(jù)
循環(huán)數(shù)據(jù)越小,兩者差別也就越小,但是數(shù)據(jù)量越大,差別也就越大。 10萬條數(shù)據(jù)的差別竟然達到上千倍!
以上就是Java優(yōu)化for循環(huán)嵌套的高效率方法的詳細內(nèi)容,更多關(guān)于Java 優(yōu)化 for循環(huán)的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
SpringBoot響應(yīng)Json數(shù)據(jù)亂碼通過配置的解決
這篇文章主要介紹了SpringBoot響應(yīng)Json數(shù)據(jù)亂碼通過配置的解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11IO密集型任務(wù)設(shè)置線程池線程數(shù)實現(xiàn)方式
這篇文章主要介紹了IO密集型任務(wù)設(shè)置線程池線程數(shù)實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-07-07