2016-04-08 85 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