3 способа сгладить список списков. Есть ли причина предпочесть один из них?

Предположим, что у нас есть список следующим образом. CoreResult имеет поле типа List<Double>.

final List<CoreResult> list = new LinkedList<>(SOME_DATA);

Цель состоит в том, чтобы сгладить список после извлечения этого конкретного поля из каждого объекта CoreResult. Вот три возможных варианта. Кто-нибудь из них предпочтительнее других?

Вариант 1: извлеките поле через map() и сгладьте внутри коллектора

final List<Double> A = list.stream().map(CoreResult::getField)
            .collect(ArrayList::new, ArrayList::addAll, ArrayList::addAll);

Вариант 2: извлечение поля через map(), сглаживание через flatMap(), простой сборщик

final List<Double> B = list.stream().map(CoreResult::getField)
            .flatMap(Collection::stream).collect(Collectors.toList());

Вариант 3: извлечение поля и сглаживание за один раз через flatMap(), простой сборщик

final List<Double> C = list.stream().flatMap(
             x -> x.getField().stream()).collect(Collectors.toList());

Будет ли ответ другим, если нет необходимости извлекать какое-либо поле из CoreResult, и вместо этого нужно просто сгладить List<List<Double>>?

Ответ 1

Я не уверен в производительности каждого из них, но важным аспектом шаблона построителя, используемого потоками java, является то, что он позволяет читать. Я лично считаю, что вариант 2 является самым читаемым. Вариант 3 тоже хорош. Я бы избегал вариант один, потому что он вроде как "обманывает" уплощение коллекции.

Поместите каждый метод в свою собственную строку и определите, какой из них наиболее интуитивно понятен для чтения. Мне нравится второй:

final List<Double> B = list.stream()
                           .map(CoreResult::getField)
                           .flatMap(Collection::stream)
                           .collect(Collectors.toList());

Ответ 2

Я бы выбрал вариант 2 или 3. Если вы хотите сгладить List<List<Double>>, вы бы сделали следующее:

List<Double> list = doubleList.stream()
                              .flatMap(List::stream)
                              .collect(Collectors.toList());

Ответ 3

Вариант 3 и 2 тот же, так что до вас, если вы хотите отобразить первую, а затем плоскую карту или просто плоскую карту.

С помощью опции 1 вам нужно открыть другой поток для выполнения дальнейших операций.