Как можно замапить стрим в новые объекты? Или, эти примеры что не равнозначны?
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;
}
в первом случае у меня все замапилось одним объектом
Ответ
Почему не работает первый вариант
При выполнении строчки
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)
Комментариев нет:
Отправить комментарий