2017-05-09 68 views
1

我不確定散列表內容如何改變。散列表替換值

下面是我的代碼:

public static void main(String args[]){ 

    HashMap<String, Double> map= new HashMap<>(); 
    map.put("com.x",30.00d); 
    map.put("com.y",70.00d); 
    map.put("com.z",70.00d); 

    List<String> readyServers=new ArrayList<>(); 
    readyServers.add("system-01"); 
    readyServers.add("system-02"); 

    returnServerMapping(2,170.00d,map,readyServers); 
} 



private static void returnServerMapping(int serverRequired, double totalExpectedExecutionTime, 
                    HashMap<String, Double> map, List<String> readyServers) { 
    Map<String,List<String>> testSuiteAndServerMap= new HashMap<>(); 
    List<String> suitesForServer = new ArrayList<>(); 

    Double executionTimePerServer = totalExpectedExecutionTime/serverRequired; 

    int currentServerNumber = 1; 
    Double currentTime = 0.0d; 
    for (Map.Entry<String, Double> entry : map.entrySet()) { 
     Double t = entry.getValue(); 

     System.out.println(currentServerNumber + " of " + serverRequired + ": " + entry.getKey()); 
     suitesForServer.add(entry.getKey()); 
     System.out.println("1.suites:"+suitesForServer); 

     currentTime += t; 

     if(currentServerNumber == serverRequired){// In the last case, let's get the all remaining suites & finally map this list with the last server 
     }else if(currentTime >= executionTimePerServer && currentServerNumber < serverRequired){ 
      System.out.println("Putting data into the map : server:"+readyServers.get(currentServerNumber-1)+"="+suitesForServer); 
      System.out.println("2.suites:"+suitesForServer); 
      testSuiteAndServerMap.put(readyServers.get(currentServerNumber-1), suitesForServer); 
      suitesForServer.removeAll(suitesForServer); 
      System.out.println("3.suites:"+suitesForServer); 
      currentServerNumber++;currentTime = 0.0d; 
     } 
    } 
    System.out.println("4.suites:"+suitesForServer); 
    testSuiteAndServerMap.put(readyServers.get(serverRequired-1), suitesForServer); 
    System.out.println("Final servers & suites:"+testSuiteAndServerMap); 
} 

和輸出

1 of 2: com.z 
1.suites:[com.z] 
1 of 2: com.y 
1.suites:[com.z, com.y] 
Putting data into the map : server:system-01=[com.z, com.y] 
2.suites:[com.z, com.y] 
3.suites:[] 
2 of 2: com.x 
1.suites:[com.x] 
4.suites:[com.x] 
Final servers & suites:{system-01=[com.x], system-02=[com.x]} 

所以現在的問題是,當系統01 = [com.z,com.y]那麼怎麼來它是在最後設置爲system-01 = [com.x]?

編輯:調試後,我發現hashmap的內容 之前suitesForServer.removeAll(suitesForServer); => key-system-01 & value 0-com.z,value 1-com.y

after suitesForServer.removeAll(suitesForServer); => key-system-01 & value size = 0

已解決:HashMap指的是列表。一旦列表內容被改變(在任何地方),hashmap也修改了內容。爲了解決這個問題,我使用了一個只拷貝列表內容的淺拷貝。

List<String> suites= new ArrayList<>(suitesForServer); 
       testSuiteAndServerMap.put(readyServers.get(currentServerNumber-1), suites); 
+3

調試程序。然後你就可以一步一步看到發生了什麼。 – f1sh

+3

簡化了代碼,並保留了您認爲自己遇到問題的唯一部分。 – Ultraviolet

+1

我相信你的問題可能與此:'currentServerNumber-1' 我可能是錯的,因爲我沒有測試它,但從一目瞭然似乎可能是罪魁禍首 – DCON

回答

1

您的地圖的值始終是相同的列表實例。 將清單放入地圖else後,您可以通過suitesForServer.removeAll(suitesForServer)清除地圖。 我建議在您的if中將com.x添加到列表中。

在每次迭代中你應該創建一個新的List實例:

for (Map.Entry<String, Double> entry : map.entrySet()) { 
    List<String> suitesForServer = new ArrayList<>(); 
    ... 
+0

謝謝!即使我在循環內初始化它,在循環之後我仍然想要保留東西。相反,我使用列表 suites = new ArrayList <>(suitesForServer);內部在else循環中。這個淺表有助於hashmap不引用在頂部初始化的任何對象。 –