Страницы

Поиск по вопросам

воскресенье, 15 декабря 2019 г.

Java 8 stream map to new Objects

#java #map #java_8 #java_stream


Как можно замапить стрим в новые объекты? Или, эти примеры что не равнозначны?

list.stream().map(new SomeObject()::convertToSomeObject)

list.stream().map(item -> new SomeObject().convertToSomeObject(item))

public SomeObject convertToSomeObject(Item item) {
    this.name = item.getName;
    this.value = item.getValue;
    return this;
}


в первом случае у меня все замапилось одним объектом 
    


Ответы

Ответ 1



Почему не работает первый вариант При выполнении строчки list.stream().map(new SomeObject()::convertToSomeObject) происходит следующее: до вызова метода map создаётся новый объект SomeObject ссылка на метод этого объекта передаётся в качестве параметра-лямбды в метод map берутся по очереди все элементы старого потока, к ним применяется переданный метод из полученных в результате применения метода новых объектов создаётся новый поток Здесь объект SomeObject создаётся ровно один раз, и так как его метод convertToSomeObject всегда возвращает единственный созданный экземпляр, то и получается, что новый поток состоит из ссылок на один и тот же объект. При этом метод convertToSomeObject вызывался для каждого элемента потока и каждый раз значения полей объекта перезаписывались Почему работает второй варинат При выполнении строчки list.stream().map(item -> new SomeObject().convertToSomeObject(item)) происходит следующее: никаких объектов SomeObject до вызова map не создаётся в метод map передаётся лямбда-функция, которая работает как обычная функция: принимает объект item создаёт новый экземпляр класса SomeObject вызывает метод convertToSomeObject у созданного экземпляра возвращает результат вызова метода convertToSomeObject, то есть только что созданный экземпляр класса SomeObject заметим, что лямбда-функция создаёт новый объект при каждом вызове Как исправить первый вариант написать конструктор SomeObject, принимающий Item в качестве параметра: public SomeObject(Item item) { this.name = item.getName(); } list.stream().map(SomeObject::new) добавить в класс SomeObject статический метод, принимающий Item и возвращающий SomeObject: public static SomeObject convertToSomeObject(Item item) { SomeObject object = new SomeObject(); object.name = item.getName(); return object; } list.stream().map(SomeObject::convertToSomeObject) Перенести метод convertToSomeObject в класс Item: public SomeObject convertToSomeObject() { SomeObject object = new SomeObject(); object.name = this.getName(); return object; } list.stream().map(Item::convertToSomeObject)

Комментариев нет:

Отправить комментарий