2015-06-03 5 views
8

Jestem nowy w Java 8. Nie jestem w stanie zrozumieć, co jest nie tak w poniższym kodzie. Pomysł polega na wysłaniu Collection<User>, jeśli nie jest pusta. Ale jeśli kolekcja jest pusta, niż wysłano odpowiedź jednostki Entity HttpStatus.NOT_FOUND.Jak sprawdzić, czy kolekcja nie jest pusta przy użyciu strumienia Javy

@RequestMapping(value = "/find/pks", 
       method = RequestMethod.GET, 
       produces = MediaType.APPLICATION_JSON_VALUE) 
public ResponseEntity<Collection<User>> getUsers(@RequestBody final Collection<String> pks) 
{ 
    return StreamSupport.stream(userRepository.findAll(pks).spliterator(), false) 
     .map(list -> new ResponseEntity<>(list , HttpStatus.OK)) 
     .orElse(new ResponseEntity<>(HttpStatus.NOT_FOUND)); 
} 

Eclipse pokazuje mi błąd w następnym punkcie .orElse

Sposób orElse(new ResponseEntity<>(HttpStatus.NOT_FOUND)) jest nieokreślony dla rodzaju Stream<ResponseEntity<User>>

Moja metoda interfejs baza wygląda jak po

Iterable<T> findAll(Iterable<PK> pks); 
+3

Stream.map() zwraca strumień, a Stream nie ma metody orElse(). Powodujesz, że twoje własne życie jest skomplikowane, zwracając Iterable. Dlaczego nie zwrócisz listy lub zestawu, a nawet kolekcji i użyjesz funkcji isEmpty()? BTW, to, co mapujesz, nie jest listą, to użytkownik.Jeśli naprawdę chcesz nadal używać Iterable, użyj iterable.iterator(). HasNext(), aby sprawdzić, czy jest pusty, czy nie. –

+0

Interfejs jest dostarczany przez jeden z pakietów Spring.)))) –

+2

Następnie użyj iterable.iterator(). HasNext(), aby sprawdzić, czy jest pusty, czy nie. Ale to powiedziawszy, nie zwróciłbym 404 w takim przypadku. po prostu zwróć 200 z pustą listą. 404 jest dla nieznanego zasobu, który próbujesz zdobyć. Wyszukujesz tutaj zasoby, a znalezienie niczego nie jest prawidłowym wynikiem. –

Odpowiedz

4

Jesteś mieszania dwóch rzeczy. Pierwszym zadaniem jest przekształcenie Iterable do Collection które można rzeczywiście rozwiązać stosując Stream API:

Collection<User> list= 
    StreamSupport.stream(userRepository.findAll(pks).spliterator(), false) 
    .collect(Collectors.toList()); 

Zauważ, że ten strumień jest strumień User ów, a nie strumień list. Dlatego nie można zmapować pliku list na coś innego z tym strumieniem. Operacja map zmapuje każdy element strumienia do nowego elementu.

Następnie można użyć tej listy, aby utworzyć ResponseEntity

return list.isEmpty()? new ResponseEntity<>(HttpStatus.NOT_FOUND): 
         new ResponseEntity<>(list, HttpStatus.OK); 

Można łączyć kroki tworząc Collector wykonywania tej czynności, choć nie daje żadnych korzyści, to tylko kwestia stylu:

ResponseEntity<User> responseEntity= 
    StreamSupport.stream(userRepository.findAll(pks).spliterator(), false) 
    .collect(Collectors.collectingAndThen(Collectors.toList(), 
     list -> list.isEmpty()? new ResponseEntity<>(HttpStatus.NOT_FOUND): 
           new ResponseEntity<>(list, HttpStatus.OK))); 
+0

Wielkie dzięki za pomoc. Zmodyfikowałem twój kod i zawarłem funkcję mapowania, aby przekonwertować każdego użytkownika na UserDTO. "StreamSupport.stream (userRepository.findAll (pks) .spliterator(), false) .map (UserDTO :: new) .collect ( Collectors.collectingAndThen (Collectors.toList(), list -> list.isEmpty()? New ResponseEntity <> (HttpStatus.NOT_FOUND) : new ResponseEntity <> (list, HttpStatus.OK))); –

1

To zależy od twojego końcowego działania strumienia, pamiętaj, że strumień może zostać zużyty tylko jeden raz.

  • Czy jest to operacja grupowania według/statystyki? Wtedy dostaniesz 0 lub pustą mapę grup.
  • Jeśli zbierze się do listy, to jest to pusta lista.
  • Jeśli jest to jedna z metod zwracających wartość Optional (na przykład findAny), można użyć opcjonalnych metod sprawdzania wartości null.
+0

Ale czy nie jest to koncepcja, której szuka, aby płynąć i przechodzić, ale czy logika stronicowania, kiedy coś faktycznie przechodzi? Więc nie przerywaj koncepcji strumieniowania lub konsumpcji raz ... –

5

Nie jest konieczne, a często pomyłka, wrzucanie wszystkiego do jednej linii. W takim przypadku nie możesz - nie ma takiego API dla twojej intencji.

Keep it simple:

Collection<User> list = <your stream code that gets a list>; 
if (list.isEmpty()) 
    return new ResponseEntity<>(HttpStatus.NOT_FOUND); 
return new ResponseEntity<>(list, HttpStatus.OK); 

ale jeśli absolutnie koniecznością:

return <your code>.map(list -> new ResponseEntity<>(list, list.isEmpty() ? HttpStatus.NOT_FOUND : HttpStatus.OK)); 
+0

Zadaje uproszczoną wersję ogólnego problemu. Jeśli filtrowanie zostało zastosowane do kolekcji, która wytworzyła strumień, nie będzie oczywiste, czy jest ona pusta, czy nie. –