When working with immutable objects, what is the best way to return a copy with modified fields?

The Java 8 Streams API allows you to create code functionally, not necessarily. Since we know that immutability provides many advantages, and as such, I try to make objects immutable wherever possible. In everyday programming, I find myself in a situation where I want to "set" a value. My objects are immutable, so I need to create a new object and initialize the field in the constructor.

I am using the Lombok project, which provides annotations, such as @Value, which essentially make the object immutable. It also has @Builderone that uses the builder pattern to provide a builder for an immutable object by setting fields not specified in the free API before null.

The annotation @Builderhas a field with a name toBuilderthat, if true, provides a method toBuilder()that returns a builder filled with the fields of the object, where the developer can "set" the values, call build()and return a new object.

eg. to create Listimmutable objects with modified fields forename, I would do the following:

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import lombok.Builder;
import lombok.Value;

public class SOExample {

    @Value
    @Builder(toBuilder = true)
    private static class Person {
        private final String forename;
        private final String surname;
        private final int age;
        private final int heightInCm;
    }

    public static void main(String[] args) {
        List<Person> people = Arrays.asList(Person.builder()
                .forename("stack")
                .surname("overflow")
                .age(21)
                .heightInCm(180)
                .build());
        people.stream()
                .map(p -> p.toBuilder()
                        .forename("updatedForename")
                        .build())
                .collect(Collectors.toList());
    }
}

. , , , . . ? , .

, () API ?

+4
4

, Java 8 Time API, withXxx(), . LocalDate :

  • withYear(int year) - LocalDate .

  • withMonth(int month) - LocalDate .

  • withDayOfMonth(int dayOfMonth) - LocalDate .

+4

, ?

, , , , .

, ( ) ; Builder.

Person personA = ...

Person personB = new Person("updated", personA.getSurname(), personA.getAge(), ...);
+3

Lombok , :

@Wither
class Person {....}

people.stream()
            .map(p -> p.withForename("updatedForename"))

, Builder. . toBuilder .

, (, AutoValue ).

+2

, . / , , , , .

:

, Java 8 Time API, Xxx()

, maaartinus Lombok @Wither . , , , Lombok @Builder(toBuilder=true) .

:

( ). . Lombok toBuilder @What

. , API Streams.

, , Scala , - Lombok @Wither @Builder(toBuilder=true), , .

:

?

, " Java" , , E.G. LocalDate.

, API Streams , . , Lombok, , . - , , , ​​Java .

0

Source: https://habr.com/ru/post/1685337/


All Articles