Spring WebFlux Reactor - Обновление объекта в Flux - PullRequest
1 голос
/ 05 ноября 2019

Учитывая следующий метод:

Flux<Person> getAllPerson(Criteria criteria) 

Как мне обработать поток, изменив поле в каждом из объектов Person в потоке?

getAllPerson(criteria)
                .map(person -> person.setLastUpdated(new Date())

setLastUpdated (new Date()) возвращает void

Я пробовал много разных способов, но не могу придумать, как его скомпилировать, например:

getAllPerson(criteria)
                .map(person -> {
                     person.setLastUpdated(new Date())
                     return person;
                 });

Ответы [ 2 ]

1 голос
/ 05 ноября 2019

Вы можете использовать оператор doOnNext, который предназначен для выполнения такого рода побочных действий.

Хотя, как правило, лучше сохранять класс Person неизменным и когда вам потребуетсяизмените что-то, вы просто создадите его копию, в этом случае вы сможете использовать оператор карты, как и ожидалось.

0 голосов
/ 05 ноября 2019

Ваш второй пример:

getAllPerson(criteria)
            .map(person -> {
                 person.setLastUpdated(new Date())
                 return person;
             });

... не скомпилируется, но только потому, что в строке setLastUpdated() отсутствует точка с запятой.

Однако, безусловно, лучшее , что нужно сделать здесь (как уже предлагалось), это сделать ваш Person класс неизменным. Затем вы можете использовать шаблон "вянут" (либо используя lombok или вашу собственную реализацию), чтобы просто сделать:

getAllPerson(criteria)
            .map(person -> person.withLastUpdated(new Date()));

Если вы не можете сделать Person неизменным (либо потому, что это внешняя библиотека, либо ее изменчивость просто слишком запекается в существующий код), тогда еще не все потеряно. Вы по-прежнему можете довольно легко создать неизменяемую обертку, например:

class ImmutablePerson {
    Person person;

    public ImmutablePerson(Person p) {
        this.person = p;
    }

    public Person withFirstName(String name) {
        return new Person(name, person.getLastName(), person.getLastUpdated());
    }

    public Person withLastName(String name) {
        return new Person(person.getFirstName(), name, person.getLastUpdated());
    }

    public Person withLastUpdated(Date date) {
        return new Person(person.getFirstName(), person.getLastName(), date);
    }

    public String getFirstName() {return person.getFirstName();}
    public String getLastName() {return person.getLastName();}
    public Date getLastUpdated() {return person.getLastUpdated();}
    public Person toPerson() {return new Person(person.getFirstName(), person.getLastName(), person.getLastUpdated());}
}

. Затем вы можете просто сопоставить ImmutablePerson на первом шаге вашей реактивной цепочки, например:

getAllPerson(criteria)
        .map(ImmutablePerson::new)
        .map(p -> p.withLastUpdated(new Date()))
        //etc.
...