2016-04-08 123 views
12

我有下面的代碼,其迭代Cookies重置其名稱匹配CookieSession.NAME轉換陣列迭代lambda表達式

Cookie[] cookies = httpServletRequest.getCookies(); 
     LOGGER.info("Clearing cookies on welcome page"); 
     if (cookies != null) 
      for (Cookie cookie : cookies) { 
       if (cookie.getName().equals(CookieSession.NAME)) {      
       cookie.setValue(null); 
       cookie.setMaxAge(0); 
       cookie.setPath("/"); 
       httpServletResponse.addCookie(cookie); 
       } 
      } 

可以使用Java 8 Lambda表達式有人把它簡化餅乾

+3

是的。但是如果條件爲 – njzk2

+7

,則可以從缺少「{}」開始。不是,不。它不會被簡化;它會基本相同,但有點複雜。 –

+0

蘭姆達斯不會讓這個更簡單。速度更慢,內存更重,但並不簡單。 – Boann

回答

8

不知道它會被簡化,但是這是可以做到的,是:

Arrays.stream(cookies) 
     .filter(c -> c.getName().equals(CookieSession.NAME)) 
     .forEach(cookie -> { 
      cookie.setValue(null); 
      cookie.setMaxAge(0); 
      cookie.setPath("/"); 
      httpServletResponse.addCookie(cookie); 
     }); 
+2

從技術上講,它不等同於OP的代碼丟失了括號,只有第一個setter會依賴於if ...但是無論如何,你的代碼不會做他期望的。 –

+1

值得指出的是,空檢查仍然需要完成。如果沒有cookie並且'Arrays.stream'不是空的,'httpServletRequest.getCookies()'返回'null'。此外,由於'HttpServletResponse'沒有被指定爲線程安全,因此'.Eeach'可以更好地替換爲'forEachOrdered' – Misha

5

for循環可以用替代表達:

Arrays.stream(cookies) 
     .filter(c -> c.getName().equals(CookieSession.NAME)) 
     .forEach(c -> {c.setValue(null); 
        c.setMaxAge(0); 
        c.setPath("/"); 
        httpServletResponse.addCookie(c); 
        }); 
5
Arrays.stream(httpsServletRequest.getCookies()) 
    .filter(cookie -> CookieSession.NAME.equals(cookie.getName())) 
    .forEach(cookie -> { 
     cookie.setValue(null); 
     cookie.setMaxAge(0); 
     cookie.setPath("/"); 
     httpServletResponse.addCookie(cookie); 
    }); 
5

其他的答案似乎忽略了if (cookies != null)。我也喜歡peek幾個中間操作,而不是一個塊。似乎對我更加清楚。

Optional.ofNullable(httpServletRequest.getCookies()) 
    .ifPresent(cookies -> Arrays.stream(cookies) 
     .filter(cookie -> cookie.getName().equals(CookieSession.NAME)) 
     .peek(cookie -> cookie.setValue(null)) 
     .peek(cookie -> cookie.setMaxAge(0)) 
     .peek(cookie -> cookie.setPath("/")) 
     .forEach(httpServletResponse::addCookie)); 
4

使用lambda或forEach無法簡化此操作。

而且,很多人都認爲你不應該使用forEach在這樣的行變異狀態:

cookies.forEach(cookie -> httpServletResponse.addCookie(cookie)); 

然而,這的確是一個風格問題。只要forEach按順序(而不是並行)消耗元素,就沒有什麼東西可以像這樣的線條實際出錯。

Here is Oracle's advice on the subject

在我看來,你應該保持原樣。

+0

我擔心你對Oracle的建議的陳述可能會誤導一些讀者。在forEach中修改狀態沒有任何不安全的地方。您提供的鏈接反對使用'forEach'出於文體原因 - 作爲提供沒有考慮使用映射和縮減的更好功能解決方案的證據。 – sprinter

+1

感謝您的編輯。我會刪除我的原始評論以避免混淆。我真的同意你的觀點,即新版本是否更好。但似乎這個世界正在發揮作用,所以我們最好習慣它:-) – sprinter