Java 8 stream map to new Objects

233
24 ноября 2017, 06:36

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

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;
}

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

Answer 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)
Answer 2

В данном случае эти примеры не равнозначны:

  • new SomeObject()::convertToSomeObject - здесь один раз создаётся новый объект SomeObject и передаётся ссылка на метод convertToSomeObject конкретно этого объекта
  • item -> new SomeObject().convertToSomeObject(item) - здесь для каждого элемента создаётся свой объект SomeObject и уже у него вызывается метод

Для использования ссылки на метод с поведением, как во втором случае, нужно создавать новый объект внутри этого метода, например, так:

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

и затем использовать как list.stream().map(SomeObject::convertToSomeObject).

READ ALSO
Glassfish NullPointeException сервер не запускается

Glassfish NullPointeException сервер не запускается

Только скачал архив GlassFish 50 - Full Platform, разархивировал его, запускаю через командную строку

466
после hover() возвращать прежнее значение backgroundColor

после hover() возвращать прежнее значение backgroundColor

Задача такая при наведении на элемент менять его backgroundColor, после того как отводишь мышку, должно возвращаться старое значение backgroundColor

259
Модальное окно по клику на button

Модальное окно по клику на button

Есть кнопка отправки формы buttonПо клику на нее в конце должно появляться модальное окно

291
Проблема с animation css

Проблема с animation css

Здравствуйте! Сделал анимации, работают, но после окончания анимации, элемент возвращается на стартовую позицию ( 0% )Вопрос: как сделать так,...

239