2017-08-28 36 views
0

我想優化下面的代碼片段。我想通過使用單個循環清除java中的多個會話密鑰。所以要求我不想清除所有的會話密鑰,我想保留一些會話密鑰。例如,在下面的代碼片段中,我試圖刪除包含ID_NAME_的密鑰,並保留傳遞給該方法的ID。如何高效地刪除Java中的多個會話密鑰?

下面的代碼片段,我寫的正常工作:

private void clearPreviousIdFromSession(HttpServletRequest request, String id) { 

     HttpSession session = request.getSession(); 
     Enumeration keys = session.getAttributeNames(); 
     ArrayList<String> keyArrs = new ArrayList<>(); 
     while (keys.hasMoreElements()) { 
      String key = (String) keys.nextElement(); 
      System.out.println("Keys for session : " + key); 

      if (key.contains("ID_NAME_"+id)) { 
       continue; 
      } else if(key.contains("ID_NAME_")) { 

       keyArrs.add(key); 

      } 
     } 

     for(String k : keyArrs){ 
      System.out.println(k); 
      session.setAttribute(k, null); 
      session.removeAttribute(k); 
     } 

    } 

下面是我試圖把它做成一個循環的代碼,但得到一個錯誤,因爲removeAttribute()將刪除與綁定的對象來自此會話的指定名稱。在這種情況下,我認爲key將被刪除,並且將無法檢查列表中的下一個元素。

private void clearPreviousIdFromSession(HttpServletRequest request, String id) { 

     HttpSession session = request.getSession(); 
     Enumeration keys = session.getAttributeNames(); 
     //ArrayList<String> keyArrs = new ArrayList<>(); 
     String key; 
     while (keys.hasMoreElements()) { 

      key = (String) keys.nextElement(); 

      System.out.println("Keys for session : " + key); 

      if (key.contains("ID_NAME_" + id)) { 
       continue; 
      } else if (key.contains("ID_NAME_")) { 

       session.removeAttribute(key); 

      } 

     } 

    } 

任何改善我的代碼的建議。我試過尋找here和一些堆棧溢出問題和here的老問題,但仍然有困難。 TIA

+1

能 「ID_NAME_」 或 「ID_REPO_」 真的出現在字符串中的任何地方?如果他們只能在開始時出現,你應該使用'startsWith'而不是'contains',這兩者都是爲了表現(小),所以你不會在某一天(!)得到一個不好的驚喜。另外,你爲什麼要調用你的'keyArrs'列表?你是海盜嗎?我只是稱它爲「鑰匙」。 –

+1

是@DavidConrad,「ID_NAME」出現在字符串的開頭。我可以使用startsWith。感謝您指出了這一點。另外,我不需要爲第二種解決方案使用'keyArrs'。我已經在第一個解決方案中使用'keys'進行枚舉。我意識到我應該使用更好的命名約定。 – Techiee

回答

2

你想優化已經設計好的東西。
由於您不應在元素迭代過程中移除元素,因此您需要收集要刪除到元素中的元素,並在迭代後迭代此列表以刪除它們。
這種方法很好,邏輯流程是「優化的」。

如果你要真正改變的東西在實際的代碼,它可能是多餘的操作:

session.setAttribute(k, null); 
session.removeAttribute(k); 

你應該選擇只有一個:

for(String k : keyArrs){ 
    System.out.println(k); 
    session.removeAttribute(k); 
} 

因爲session.setAttribute(k, null)有與致電session.removeAttribute(k)的效果相同。

+0

謝謝大衛指出'session.setAttribute(k,null)',是的,我可以刪除它。但我在想如果我可以同時做兩個(迭代和刪除)。 – Techiee

+1

不客氣。我不認爲'Enumeration'類不會被設計爲在迭代過程中像'Iterator'一樣去除元素。 – davidxxx

1
if (key.contains("ID_REPO_" + id)) { 
       continue; 
      } else if (key.contains("ID_REPO_")) { 

       session.removeAttribute(key); 

      } 

重構這對Java流:

key.stream() 
.filter(key -> !key.contains("ID_REPO_" + id)) //filter all keys that do not have string 
.forEach(key -> session.removeAttribute(key)) // execute lambda on every key filtered 
+0

您的解決方案對我來說很好。只有我使用Java 7的東西。我能在7中使用它嗎? – Techiee

相關問題