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 вам нужно открыть другой поток для выполнения дальнейших операций.