2016-04-08 16 views
12

Mam poniżej kod, który wykonuje iteracje nad Cookies zresetować ciasteczko, którego nazwa pasuje CookieSession.NAMEKonwersja Array iteracji do wyrażenia 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); 
       } 
      } 

może ktoś uprościć używając Java 8 lambda wyrażenia

+3

tak. ale możesz zacząć od naprawienia braku '{}' w twoim wariancie jeśli nie jest to – njzk2

+7

Nie, nie. Nie zostanie uproszczone; będzie w zasadzie taki sam, ale trochę bardziej skomplikowany. –

+0

Lambda nie sprawi, że stanie się to prostsze. Wolniej, więcej pamięci, ale nie prostsze. – Boann

Odpowiedz

8

Nie wiem, czy to będzie zostać uproszczone, ale można to zrobić tak:

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

Technicznie nie będzie to równoznaczne, ponieważ w kodzie OP brakuje nawiasu, a tylko pierwszy seter będzie zależał od tego, czy ... ale w każdym razie twój kod robi to, czego się spodziewa. –

+1

Warto zauważyć, że nadal konieczne jest sprawdzenie wartości zerowej. 'httpServletRequest.getCookies()' zwraca 'null', jeśli nie ma plików cookie, a' Arrays.stream' nie jest wartością zerową. Ponadto, ponieważ 'HttpServletResponse' nie jest określony jako bezpieczny dla wątków,' .forEeach' lepiej zastąpić 'forEachOrdered' – Misha

5

pętla for mogłyby zostać zastąpione forEach wyrażenie:

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

Inne odpowiedzi wydają się być ignorowane if (cookies != null). Również lubię peek dla kilku operacji pośrednich, a nie blok. Wydaje mi się jaśniejszy.

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

Nie można tego uprościć za pomocą lambda lub forEach.

Ponadto, wiele osób uważa, że ​​nie należy używać forEach mutować stanu w linii tak:

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

Jednak jest to naprawdę kwestia stylu. Dopóki forEach zużywa elementy sekwencyjnie (a nie równolegle), nic nie może pójść źle w wyniku takiej linii.

Here is Oracle's advice on the subject.

Moim zdaniem, należy pozostawić swój kod w niezmienionym stanie.

+0

Obawiam się, że twoje oświadczenie dotyczące porady Oracle może wprowadzić niektórych czytelników w błąd. Nie ma nic niebezpiecznego w modyfikowaniu stanu w 'forEach'. Podany link przemawia przeciwko użyciu "forEach" ze względów stylistycznych - jako dowód na to, że nie myślisz o lepszym funkcjonalnym rozwiązaniu z wykorzystaniem mapowania i redukcji. – sprinter

+1

Dzięki za edycję. Usuwam swój pierwotny komentarz, aby uniknąć nieporozumień. Zgadzam się z twoim punktem widzenia, czy nowa wersja jest lepsza. Wygląda jednak na to, że świat funkcjonuje, więc lepiej się do tego przyzwyczaić :-) – sprinter