Alexander Petrov
Alexander Petrov

Reputation: 9492

Update immutable object without breaking immutability

how can I get updated immutable object from another immutable object without breaking the immutability in a good way. Something similar to how things are achieved in Scala or how they are achieved in Immutables library.

How can I achieve something like Customer.Builder.from(anotherCustomer).replaceOrder(oldOrder,newOrder).with(newName).build()

To reuse the old objects and queue all the changes I want in order to construct a new one.

I am using Java.

Upvotes: 4

Views: 12033

Answers (4)

Martin Cremer
Martin Cremer

Reputation: 5572

Here's a little recursive function that creates a changed immutable. It re-creates every nested object that includes the change.

const changeImmutable = (immutable: any, path: string[], newVal: any): any => {
  if(path.length) {
    let copy = Array.isArray(immutable) ? [...immutable] : {...immutable};
    copy[path[0]] = changeImmutable(copy[path[0]], path.slice(1), newVal);
    return copy;
  }
  return newVal; 
};

example of usage

let immutableObj = {a: {b: [{c: 'foo'}]}};

// change 'foo' to 'bar'
let newImmutableObj = changeImmutable(immutableObj, ['a', 'b', 0, 'c'], 'bar');

Upvotes: 1

Gab
Gab

Reputation: 8323

public class Customer {
    private String name;    
    private Order order

    private Customer(CustomerBuilder builder) {
        this.name = builder.name;
        this.order = builder.order;
    }

    public Customer replace(Order order) {
        return new CustomerBuilder().name(this.name).order(order).build();
    }

    public static class CustomerBuilder {
        private String name;    
        private Order order

        public CustomerBuilder name(String name) {
            this.name = name;
            return this;
        }

        public CustomerBuilder order(Order order) {
            this.order = order;
            return this;
        }

        public Customer build() {
            return new Customer(this);
        }
    }
}

Upvotes: 6

nukie
nukie

Reputation: 681

You can implement Cloneable interface in object type. Another option is to have builder for your immutable objects which can create new instance from existing one. Something like those fellas done...

Upvotes: 0

Saloparenator
Saloparenator

Reputation: 330

I recommend this book who cover the subject : https://www.amazon.ca/Effective-Java-Edition-Joshua-Bloch/dp/0321356683

Best way I know to update immutable object is to return modified copy of the object, like java String

    String uppercase = "hello".toUpperCase()

I make easy to use fluent typing

    String uppercasewithoutletterL = "hello".toUpperCase().replace("L","")

Upvotes: 1

Related Questions