2

I have the following service method:

public void create(MultipartFile file) throws Exception {
      List<Employee> employees = CsvHelper.csvToEmployees(file.getInputStream()).stream()
              .map(EmployeeRequestMapper::mapToEntity)
              .collect(Collectors.toList());
     
      // Can I use Stream and throw exception if employees is empty
      if (employees.isEmpty()) {
          throw new NoSuchElementFoundException(NOT_CONTAINS_EMPLOYEE);
      }

      employeeRepository.saveAll(employees);
}

Here I read CSV file and if there is no record, throw my custom NoSuchElementFoundException exception.

However, regarding to if block, I am not sure if there is a proper way using Java Stream as I use in the following example:

public EmployeeDto findByEmail(String email) {
    return employeeRepository.findByEmail(email)
            .map(EmployeeDto::new)
            .orElseThrow(() -> new NoSuchElementFoundException(NO_ITEM_FOUND));
}

So, can I apply similar one to the create() method?

samabcde
  • 6,988
  • 2
  • 25
  • 41
  • 2
    I do not understand the question. What is the problem with the current approach of using `...orElseThrow(...)`? We normally use `Stream`s if we have multiple entries, but `findByEmail(...)` seems to return an `Optional` (i.e. 0 or 1 entries), so this is the "correct" approach. – Turing85 Jul 23 '22 at 16:47
  • I am not asking `findByEmail` method, it is ok of course. I am asking `create` method. –  Jul 23 '22 at 16:52
  • @Turing85 Why vote down? –  Jul 23 '22 at 16:52
  • No. Your clarification got the problem across. There is, however, one point unclear: are we actually talking about a `null`-value for the list, or an empty list? If we are talking about a `null` value, where can it occur? Can the parameter itself be `null`, or can the value of `CsvHelper.csvToEmployees` be null? For `null` value, the default approach is using `Optional.ofNullable(...).orElseThrow(...)`. There is -as far as I know, no possibility to check if a `Stream` is empty without consuming it. So the depature of converting it to a `List` and checking that seems like a plausible solution. – Turing85 Jul 23 '22 at 17:04
  • @Turing85 Regarding to null, you are right I meant "Empty" and corrected comment, sorry. As it is a list, when there is no record it will return null list and I want to handle this situation. But I am not sure if there is an elegant solution instead of using if block. Any idea? –  Jul 23 '22 at 17:08
  • 1
    Wrap it in `Optional.ofNullable(...).orElseThrow(...)...`. – Turing85 Jul 23 '22 at 17:10
  • Thanks, but as it is List, I need to check empty instead of null. I tried to be sure, but unfortunately not working. Any idea for this kind of situations using Java Stream? –  Jul 23 '22 at 17:16
  • I am trying `Optional.empty(employees).orElseThrow(() -> new NoSuchElementFoundException(NO_RECORD));` –  Jul 23 '22 at 17:17
  • But `empty()` does not expect any parameter :( –  Jul 23 '22 at 17:17
  • Also tried `employees.isEmpty().orElseThrow(() -> new NoSuchElementFoundException(NO_RECORD));`, not working –  Jul 23 '22 at 17:18
  • Some people used like me, some others suggest like this (adding filter) : https://stackoverflow.com/questions/56869805/java-8-throw-exception-if-stream-returns-no-results –  Jul 23 '22 at 17:20
  • 4
    Your code is just fine the way it stands. I see no reasonable way to change it to throw the exception from within a stream pipeline. – Ole V.V. Jul 23 '22 at 17:34
  • @OleV.V. You right, I have seen that after my search. But as I have not experience for this situations, just wanted to be sure by getting some suggestions. Thanks a lot. –  Jul 23 '22 at 17:38
  • @Turing85 Thanks a lot to you also for your useful helps –  Jul 23 '22 at 17:38
  • Thanks, hans. I am not going to post an answer, so if you think you’ve got your question answered, in half or in full, consider posting your own answer to it. – Ole V.V. Jul 23 '22 at 18:23
  • If you _really_ want to use Stream/Optional to throw the exception, you can do this: `Optional.of(employees).filter(e -> !e.isEmpty()).orElseThrow(() -> new NoSuchElementException())`. But this is beating around the bush, and your use of an if statement is better. – DBear Jul 23 '22 at 20:42
  • @DBear You are right, then I will continue to use current approach. thanks a lot. –  Jul 23 '22 at 23:19

1 Answers1

0

You can use the following, which will be applied after the result is collected on the list and it will check if the result list is empty and if that is the case it will throw the exception

    public void create(MultipartFile file) throws Exception {
  List<Employee> employees = CsvHelper.csvToEmployees(file.getInputStream()).stream()
          .map(EmployeeRequestMapper::mapToEntity)
          .collect(Collectors.collectingAndThen(Collectors.toList(), result -> {
            if (result.isEmpty()) throw new NoSuchElementFoundException(NOT_CONTAINS_EMPLOYEE);
            return result;
           })); 
 employeeRepository.saveAll(employees);
 }
Panagiotis Bougioukos
  • 15,955
  • 2
  • 30
  • 47