1. 程式人生 > 程式設計 >Java優化for迴圈巢狀的高效率方法

Java優化for迴圈巢狀的高效率方法

前幾天有人問過我一個問題,就是兩個巢狀for迴圈執行效率的問題,問有什麼好的辦法替換。當時我想了想,實在想不起來,哎,慚愧!!! 請教了答案,恍然大悟。

比如:兩個list中分別裝有相同的物件資料。 list1中有3萬條物件資料。 list2中有2萬條物件資料(但是物件中的某個屬性變數為空)。兩個list中的id或者其他變數都一模一樣。請用最快的方式找出list2中變數為空的那個物件,並且去list1中找出id相同的物件。 或者可以理解成,從list2中找出變數為空的,去list1中找出對應的物件,然後把為空的列補上。總之就是這麼一個意思,先 for 迴圈 list2,判斷一下每個物件的那個屬性變數是否為空,如果為空,再去for迴圈list1,找出id一樣的物件,就算執行成功了。

那麼請看下邊的for迴圈巢狀的解決方式:

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 值為空!!!");
  }
 }
 }
}

這樣真的好嗎? 如果有上萬,甚至十幾萬的資料,那麼這個執行效率問題,我就不多說了。 非常非常的慢。

下邊來看使用map代替的執行方式,以及兩種方式的效率對比:

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),"技術客",(i+1),date));
  if(i%2==0){
  list2.add(new Member((i+1),null,date));
  }
 }
  
 //雙for迴圈巢狀測試
 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迴圈查詢時間為:"+(s2-s1)+"(毫秒),一共查詢出"+forNumber+"條資料 \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結構查詢時間為:"+(s4-s3)+"(毫秒),一共查詢出"+mapNumber+"條資料 \n\n\n");
 }
 
}

輸出結果:

雙for迴圈查詢時間為:1578(毫秒),一共查詢出15000條資料



使用map結構查詢時間為:14(毫秒),一共查詢出15000條資料

如果我們模擬10萬條資料,然後其中五千條重複資料的情況下:效率更是天壤之別。

看輸出結果:

雙for迴圈查詢時間為:30929(毫秒),一共查詢出50000條資料



使用map結構查詢時間為:24(毫秒),一共查詢出50000條資料

迴圈資料越小,兩者差別也就越小,但是資料量越大,差別也就越大。 10萬條資料的差別竟然達到上千倍!

以上就是Java優化for迴圈巢狀的高效率方法的詳細內容,更多關於Java 優化 for迴圈的資料請關注我們其它相關文章!