javajava-stream

Is it wrong to add elements into a java list, with parallel stream?


Is it better to use some of thread safe collections ? Scope of the question is only the generation and adding of elements into the list.

public List<BankDetailsDTO> generateBankDetailsDTOs(int amount) {
    List<BankDetailsDTO> result = new ArrayList<>();
    IntStream.range(0, amount).parallel().forEach(index -> {
        result.add(new BankDetailsDTO(bankDetailsDTOCounter.getAndIncrement(),
            faker.company().name(),
            faker.finance().iban(),
            faker.finance().bic(),
            faker.finance().iban()));
        });
        return result;
    }
}

Solution

  • result is an unsynchronized list, and your parallel stream is using multiple threads to mutate it concurrently. The resulting list is probably going to be corrupted (contain less than amount elements, for example).

    Change it to:

        public List<BankDetailsDTO> generateBankDetailsDTOs(int amount) {
            List<BankDetailsDTO> result = IntStream.range(0, amount).parallel()
                .mapToObj(index ->
                    new BankDetailsDTO(bankDetailsDTOCounter.getAndIncrement(),
                                faker.company().name(),
                                faker.finance().iban(),
                                faker.finance().bic(),
                                faker.finance().iban()))
                .toList();
            return result;
        }
    

    We have avoided the parallel stream to concurrently mutate a list you provided externally. Instead, we provided the Stream with a function to be applied to each element (mapToObj(...)), then we have the Stream to generate the resulting list (toList()).