This is how Clojure does it, take a look at this: https://clojure.org/reference/transients
It's great, one of the many awesome features Clojure has.