001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.juneau.commons.lang;
018
019import static org.apache.juneau.commons.utils.AssertionUtils.*;
020import static org.apache.juneau.commons.utils.Utils.*;
021
022import java.lang.reflect.*;
023import java.util.*;
024import java.util.function.*;
025
026import org.apache.juneau.commons.reflect.ClassInfo;
027
028/**
029 * A generic mutable value wrapper.
030 *
031 * <p>
032 * This class provides a simple way to wrap any object type in a mutable container, making it useful for passing
033 * mutable references to lambdas, inner classes, and methods. It is similar to {@link Optional} but allows the
034 * value to be changed after creation.
035 *
036 * <p>
037 * The class supports method chaining through fluent setters and provides various convenience methods for working
038 * with the wrapped value, including mapping, conditional execution, and default value handling.
039 *
040 * <h5 class='section'>Features:</h5>
041 * <ul class='spaced-list'>
042 *    <li>Mutable value container with fluent API
043 *    <li>Optional-like methods: {@link #get()}, {@link #orElse(Object)}, {@link #ifPresent(Consumer)}, {@link #map(Function)}
044 *    <li>Atomic-like operations: {@link #getAndSet(Object)}, {@link #getAndUnset()}
045 *    <li>Listener support for value changes via {@link ValueListener}
046 *    <li>Method chaining for all setter operations
047 * </ul>
048 *
049 * <h5 class='section'>Notes:</h5><ul>
050 *    <li class='warn'>
051 *       This class is <b>not thread-safe</b>. For concurrent access, consider using atomic classes like
052 *       {@link java.util.concurrent.atomic.AtomicReference}.
053 * </ul>
054 *
055 * <h5 class='section'>Examples:</h5>
056 * <p class='bjava'>
057 *    <jc>// Basic usage</jc>
058 *    Value&lt;String&gt; <jv>name</jv> = Value.<jsm>of</jsm>(<js>"John"</js>);
059 *    <jv>name</jv>.set(<js>"Jane"</js>);
060 *    String <jv>result</jv> = <jv>name</jv>.get();  <jc>// Returns "Jane"</jc>
061 *
062 *    <jc>// Use in lambda (effectively final variable)</jc>
063 *    Value&lt;String&gt; <jv>result</jv> = Value.<jsm>empty</jsm>();
064 *    list.forEach(<jv>x</jv> -&gt; {
065 *       <jk>if</jk> (<jv>x</jv>.matches(criteria)) {
066 *          <jv>result</jv>.set(<jv>x</jv>);
067 *       }
068 *    });
069 *
070 *    <jc>// With default values</jc>
071 *    Value&lt;String&gt; <jv>optional</jv> = Value.<jsm>empty</jsm>();
072 *    String <jv>value</jv> = <jv>optional</jv>.orElse(<js>"default"</js>);  <jc>// Returns "default"</jc>
073 *
074 *    <jc>// Mapping values</jc>
075 *    Value&lt;Integer&gt; <jv>number</jv> = Value.<jsm>of</jsm>(5);
076 *    Value&lt;String&gt; <jv>text</jv> = <jv>number</jv>.map(Object::toString);  <jc>// Value of "5"</jc>
077 *
078 *    <jc>// With listener for change notification</jc>
079 *    Value&lt;String&gt; <jv>monitored</jv> = Value.<jsm>of</jsm>(<js>"initial"</js>)
080 *       .listener(<jv>newValue</jv> -&gt; <jsm>log</jsm>(<js>"Value changed to: "</js> + <jv>newValue</jv>));
081 *    <jv>monitored</jv>.set(<js>"updated"</js>);  <jc>// Triggers listener</jc>
082 * </p>
083 *
084 * <h5 class='section'>Specialized Value Classes:</h5>
085 * <p>
086 * For primitive types and common use cases, specialized subclasses are available with additional convenience methods:
087 * <ul class='spaced-list'>
088 *    <li>{@link IntegerValue} - For mutable integers with {@code getAndIncrement()}
089 *    <li>{@link LongValue} - For mutable longs with {@code getAndIncrement()}
090 *    <li>{@link ShortValue} - For mutable shorts with {@code getAndIncrement()}
091 *    <li>{@link FloatValue} - For mutable floats
092 *    <li>{@link DoubleValue} - For mutable doubles
093 *    <li>{@link CharValue} - For mutable characters
094 *    <li>{@link BooleanValue} - For nullable booleans with {@code isTrue()}/{@code isNotTrue()}
095 *    <li>{@link Flag} - For non-nullable boolean flags (true/false only, no null state)
096 * </ul>
097 *
098 * <h5 class='section'>See Also:</h5><ul>
099 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauCommonsLang">Lang Package</a>
100 *    <li class='jc'>{@link ValueListener}
101 *    <li class='jc'>{@link IntegerValue}
102 *    <li class='jc'>{@link BooleanValue}
103 *    <li class='jc'>{@link Flag}
104 * </ul>
105 *
106 * @param <T> The value type.
107 */
108public class Value<T> {
109   /**
110    * Creates a new empty value (with <c>null</c> as the initial value).
111    *
112    * <h5 class='section'>Example:</h5>
113    * <p class='bjava'>
114    *    Value&lt;String&gt; <jv>value</jv> = Value.<jsm>empty</jsm>();
115    *    <jsm>assertNull</jsm>(<jv>value</jv>.get());
116    *    <jsm>assertTrue</jsm>(<jv>value</jv>.isEmpty());
117    * </p>
118    *
119    * @param <T> The value type.
120    * @return A new empty {@link Value} object.
121    */
122   public static <T> Value<T> empty() {
123      return new Value<>(null);
124   }
125
126   /**
127    * Convenience method for checking if the specified type is this class.
128    *
129    * @param t The type to check.
130    * @return <jk>true</jk> if the specified type is this class.
131    */
132   public static boolean isType(Type t) {
133      return (t instanceof ParameterizedType t2 && t2.getRawType() == Value.class) || (t instanceof Class t3 && Value.class.isAssignableFrom(t3));
134   }
135
136   /**
137    * Creates a new value with the specified initial value.
138    *
139    * <h5 class='section'>Example:</h5>
140    * <p class='bjava'>
141    *    Value&lt;String&gt; <jv>value</jv> = Value.<jsm>of</jsm>(<js>"hello"</js>);
142    *    <jsm>assertEquals</jsm>(<js>"hello"</js>, <jv>value</jv>.get());
143    * </p>
144    *
145    * @param <T> The value type.
146    * @param object The object being wrapped. Can be <jk>null</jk>.
147    * @return A new {@link Value} object containing the specified value.
148    */
149   public static <T> Value<T> of(T object) {
150      return new Value<>(object);
151   }
152
153   /**
154    * Returns the generic parameter type of the Value type.
155    *
156    * @param t The type to find the parameter type of.
157    * @return The parameter type of the value, or <jk>null</jk> if the type is not a subclass of <c>Value</c>.
158    */
159   public static Type getParameterType(Type t) {
160      if (t instanceof ParameterizedType t2) {
161         if (t2.getRawType() == Value.class) {
162            var ta = t2.getActualTypeArguments();
163            if (ta.length > 0)
164               return ta[0];
165         }
166      } else if ((t instanceof Class<?> t3) && Value.class.isAssignableFrom(t3)) {
167         return ClassInfo.of(t3).getParameterType(0, Value.class);
168      }
169
170      return null;
171   }
172
173   /**
174    * Returns the unwrapped type.
175    *
176    * @param t The type to unwrap.
177    * @return The unwrapped type, or the same type if the type isn't {@link Value}.
178    */
179   public static Type unwrap(Type t) {
180      var x = getParameterType(t);
181      return nn(x) ? x : t;
182   }
183
184   private T t;
185   private ValueListener<T> listener;
186
187   /**
188    * Constructor.
189    */
190   public Value() {}
191
192   /**
193    * Constructor.
194    *
195    * @param t Initial value.
196    */
197   public Value(T t) {
198      set(t);
199   }
200
201   @Override /* Overridden from Object */
202   public boolean equals(Object obj) {
203      return obj instanceof Value<?> obj2 && eq(this, obj2, (x, y) -> eq(x.t, y.t));
204   }
205
206   /**
207    * If a value is present, and the value matches the given predicate, returns a {@link Value} describing the
208    * value, otherwise returns an empty {@link Value}.
209    *
210    * <p>
211    * This method is analogous to {@link java.util.Optional#filter(Predicate)}.
212    *
213    * <h5 class='section'>Example:</h5>
214    * <p class='bjava'>
215    *    Value&lt;String&gt; <jv>value</jv> = Value.<jsm>of</jsm>(<js>"hello"</js>);
216    *    Value&lt;String&gt; <jv>filtered</jv> = <jv>value</jv>.filter(<jv>s</jv> -&gt; <jv>s</jv>.length() &gt; 3);
217    *    <jsm>assertTrue</jsm>(<jv>filtered</jv>.isPresent());
218    *
219    *    Value&lt;String&gt; <jv>filtered2</jv> = <jv>value</jv>.filter(<jv>s</jv> -&gt; <jv>s</jv>.length() &gt; 10);
220    *    <jsm>assertFalse</jsm>(<jv>filtered2</jv>.isPresent());
221    * </p>
222    *
223    * @param predicate The predicate to apply to the value, if present. Must not be <jk>null</jk>.
224    * @return A {@link Value} describing the value if it is present and matches the predicate, otherwise an empty {@link Value}.
225    */
226   public Value<T> filter(Predicate<? super T> predicate) {
227      assertArgNotNull("predicate", predicate);
228      if (t == null)
229         return Value.empty();
230      return predicate.test(t) ? this : Value.empty();
231   }
232
233   /**
234    * If a value is present, returns the result of applying the given {@link Value}-bearing mapping function to
235    * the value, otherwise returns an empty {@link Value}.
236    *
237    * <p>
238    * This method is similar to {@link #map(Function)}, but the mapping function returns a {@link Value} rather
239    * than a simple value. This is analogous to {@link java.util.Optional#flatMap(Function)}.
240    *
241    * <h5 class='section'>Example:</h5>
242    * <p class='bjava'>
243    *    Value&lt;String&gt; <jv>value</jv> = Value.<jsm>of</jsm>(<js>"hello"</js>);
244    *    Value&lt;Integer&gt; <jv>length</jv> = <jv>value</jv>.flatMap(<jv>s</jv> -&gt; Value.<jsm>of</jsm>(<jv>s</jv>.length()));
245    *    <jsm>assertEquals</jsm>(5, <jv>length</jv>.get());
246    *
247    *    <jc>// Returns empty if mapper returns empty</jc>
248    *    Value&lt;String&gt; <jv>empty</jv> = <jv>value</jv>.flatMap(<jv>s</jv> -&gt; Value.<jsm>empty</jsm>());
249    *    <jsm>assertFalse</jsm>(<jv>empty</jv>.isPresent());
250    * </p>
251    *
252    * @param <T2> The type of value in the {@link Value} returned by the mapping function.
253    * @param mapper The mapping function to apply to the value, if present. Must not be <jk>null</jk>.
254    * @return The result of applying the {@link Value}-bearing mapping function to the value if present,
255    *         otherwise an empty {@link Value}.
256    */
257   public <T2> Value<T2> flatMap(Function<? super T,? extends Value<? extends T2>> mapper) {
258      assertArgNotNull("mapper", mapper);
259      if (t == null)
260         return Value.empty();
261      var result = mapper.apply(t);
262      @SuppressWarnings("unchecked")
263      var cast = (Value<T2>)result;
264      return cast;
265   }
266
267   /**
268    * Returns the value.
269    *
270    * @return The value, or <jk>null</jk> if it is not set.
271    */
272   public T get() {
273      return t;
274   }
275
276   /**
277    * Returns the current value and then sets it to the specified value.
278    *
279    * <h5 class='section'>Example:</h5>
280    * <p class='bjava'>
281    *    Value&lt;String&gt; <jv>value</jv> = Value.<jsm>of</jsm>(<js>"old"</js>);
282    *    String <jv>oldValue</jv> = <jv>value</jv>.getAndSet(<js>"new"</js>);  <jc>// Returns "old"</jc>
283    *    String <jv>newValue</jv> = <jv>value</jv>.get();                   <jc>// Returns "new"</jc>
284    * </p>
285    *
286    * @param t The new value.
287    * @return The value before it was set.
288    */
289   public T getAndSet(T t) {
290      var t2 = this.t;
291      set(t);
292      return t2;
293   }
294
295   /**
296    * Returns the current value and then unsets it (sets to <jk>null</jk>).
297    *
298    * <p>
299    * This is useful for "consuming" a value, ensuring it can only be retrieved once.
300    *
301    * <h5 class='section'>Example:</h5>
302    * <p class='bjava'>
303    *    Value&lt;String&gt; <jv>value</jv> = Value.<jsm>of</jsm>(<js>"data"</js>);
304    *    String <jv>result</jv> = <jv>value</jv>.getAndUnset();  <jc>// Returns "data"</jc>
305    *    <jsm>assertNull</jsm>(<jv>value</jv>.get());           <jc>// Value is now null</jc>
306    * </p>
307    *
308    * @return The value before it was unset, or <jk>null</jk> if it was already <jk>null</jk>.
309    */
310   public T getAndUnset() {
311      var t2 = t;
312      t = null;
313      return t2;
314   }
315
316   @Override /* Overridden from Object */
317   public int hashCode() {
318      return t == null ? 0 : t.hashCode();
319   }
320
321   /**
322    * If a value is present (not <jk>null</jk>), invokes the specified consumer with the value, otherwise does nothing.
323    *
324    * <h5 class='section'>Example:</h5>
325    * <p class='bjava'>
326    *    Value&lt;String&gt; <jv>value</jv> = Value.<jsm>of</jsm>(<js>"hello"</js>);
327    *    <jv>value</jv>.ifPresent(<jsm>System.out</jsm>::<jv>println</jv>);  <jc>// Prints "hello"</jc>
328    *
329    *    Value&lt;String&gt; <jv>empty</jv> = Value.<jsm>empty</jsm>();
330    *    <jv>empty</jv>.ifPresent(<jsm>System.out</jsm>::<jv>println</jv>);  <jc>// Does nothing</jc>
331    * </p>
332    *
333    * @param consumer Block to be executed if a value is present. Must not be <jk>null</jk>.
334    */
335   public void ifPresent(Consumer<? super T> consumer) {
336      if (nn(t))
337         consumer.accept(t);
338   }
339
340   /**
341    * Checks if the current value equals the specified value using {@link org.apache.juneau.commons.utils.Utils#eq(Object, Object)}.
342    *
343    * <p>
344    * This method uses {@code eq()} for equality comparison, which handles <jk>null</jk> values safely
345    * and performs deep equality checks for arrays and collections.
346    *
347    * <h5 class='section'>Example:</h5>
348    * <p class='bjava'>
349    *    Value&lt;String&gt; <jv>value</jv> = Value.<jsm>of</jsm>(<js>"hello"</js>);
350    *    <jsm>assertTrue</jsm>(<jv>value</jv>.is(<js>"hello"</js>));
351    *    <jsm>assertFalse</jsm>(<jv>value</jv>.is(<js>"world"</js>));
352    *
353    *    <jc>// Handles null values safely</jc>
354    *    Value&lt;String&gt; <jv>empty</jv> = Value.<jsm>empty</jsm>();
355    *    <jsm>assertTrue</jsm>(<jv>empty</jv>.is(<jk>null</jk>));
356    *    <jsm>assertFalse</jsm>(<jv>empty</jv>.is(<js>"test"</js>));
357    *
358    *    <jc>// Works with any type</jc>
359    *    Value&lt;Integer&gt; <jv>number</jv> = Value.<jsm>of</jsm>(42);
360    *    <jsm>assertTrue</jsm>(<jv>number</jv>.is(42));
361    *    <jsm>assertFalse</jsm>(<jv>number</jv>.is(43));
362    * </p>
363    *
364    * @param other The value to compare with. Can be <jk>null</jk>.
365    * @return <jk>true</jk> if the values are equal according to {@link org.apache.juneau.commons.utils.Utils#eq(Object, Object)}.
366    */
367   public boolean is(T other) {
368      return eq(t, other);
369   }
370
371   /**
372    * Returns <jk>true</jk> if the value is empty.
373    *
374    * @return <jk>true</jk> if the value is empty.
375    */
376   public boolean isEmpty() { return t == null; }
377
378   /**
379    * Returns <jk>true</jk> if the value is set.
380    *
381    * @return <jk>true</jk> if the value is set.
382    */
383   public boolean isPresent() { return nn(get()); }
384
385   /**
386    * Registers a listener that will be called whenever the value is changed via {@link #set(Object)}.
387    *
388    * <p>
389    * Only one listener can be registered at a time. Calling this method again will replace the previous listener.
390    *
391    * <h5 class='section'>Example:</h5>
392    * <p class='bjava'>
393    *    Value&lt;String&gt; <jv>value</jv> = Value.<jsm>of</jsm>(<js>"initial"</js>);
394    *    <jv>value</jv>.listener(<jv>newValue</jv> -&gt; <jsm>log</jsm>(<js>"Changed to: "</js> + <jv>newValue</jv>));
395    *
396    *    <jv>value</jv>.set(<js>"updated"</js>);  <jc>// Triggers listener, logs "Changed to: updated"</jc>
397    * </p>
398    *
399    * @param listener The listener to be called on value changes. Can be <jk>null</jk> to remove the listener.
400    * @return This object for method chaining.
401    * @see ValueListener
402    */
403   public Value<T> listener(ValueListener<T> listener) {
404      this.listener = listener;
405      return this;
406   }
407
408   /**
409    * Applies a mapping function to the value if present, returning a new {@link Value} with the result.
410    *
411    * <p>
412    * If this value is empty (<jk>null</jk>), returns an empty value without applying the mapper.
413    *
414    * <h5 class='section'>Example:</h5>
415    * <p class='bjava'>
416    *    Value&lt;String&gt; <jv>name</jv> = Value.<jsm>of</jsm>(<js>"john"</js>);
417    *    Value&lt;String&gt; <jv>upper</jv> = <jv>name</jv>.map(String::toUpperCase);
418    *    <jsm>assertEquals</jsm>(<js>"JOHN"</js>, <jv>upper</jv>.get());
419    *
420    *    Value&lt;Integer&gt; <jv>length</jv> = <jv>name</jv>.map(String::length);
421    *    <jsm>assertEquals</jsm>(4, <jv>length</jv>.get());
422    *
423    *    Value&lt;String&gt; <jv>empty</jv> = Value.<jsm>empty</jsm>();
424    *    Value&lt;Integer&gt; <jv>result</jv> = <jv>empty</jv>.map(String::length);  <jc>// Returns empty Value</jc>
425    * </p>
426    *
427    * @param <T2> The mapped value type.
428    * @param mapper The mapping function to apply. Must not be <jk>null</jk>.
429    * @return A new {@link Value} containing the mapped result, or an empty value if this value is empty.
430    */
431   public <T2> Value<T2> map(Function<? super T,T2> mapper) {
432      assertArgNotNull("mapper", mapper);
433      if (nn(t))
434         return of(mapper.apply(t));
435      return empty();
436   }
437
438   /**
439    * Returns the contents of this value or the default value if <jk>null</jk>.
440    *
441    * @param def The default value.
442    * @return The contents of this value or the default value if <jk>null</jk>.
443    */
444   public T orElse(T def) {
445      return t == null ? def : t;
446   }
447
448   /**
449    * Return the value if present, otherwise invoke {@code other} and return
450    * the result of that invocation.
451    *
452    * @param other a {@code Supplier} whose result is returned if no value
453    * is present
454    * @return the value if present otherwise the result of {@code other.get()}
455    * @throws NullPointerException if value is not present and {@code other} is
456    * null
457    */
458   public T orElseGet(Supplier<? extends T> other) {
459      return nn(t) ? t : other.get();
460   }
461
462   /**
463    * Return the contained value, if present, otherwise throw an exception
464    * to be created by the provided supplier.
465    *
466    * @param <X> The exception type.
467    * @param exceptionSupplier The supplier which will return the exception to
468    * be thrown
469    * @return the present value
470    * @throws X if there is no value present
471    * @throws NullPointerException if no value is present and
472    * {@code exceptionSupplier} is null
473    */
474   public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
475      if (nn(t))
476         return t;
477      throw exceptionSupplier.get();
478   }
479
480   /**
481    * Sets the value.
482    *
483    * <p>
484    * If a {@link ValueListener} is registered, it will be notified of the change.
485    *
486    * <h5 class='section'>Example:</h5>
487    * <p class='bjava'>
488    *    Value&lt;String&gt; <jv>value</jv> = Value.<jsm>empty</jsm>();
489    *    <jv>value</jv>.set(<js>"hello"</js>).set(<js>"world"</js>);  <jc>// Method chaining</jc>
490    *    <jsm>assertEquals</jsm>(<js>"world"</js>, <jv>value</jv>.get());
491    * </p>
492    *
493    * @param t The new value. Can be <jk>null</jk>.
494    * @return This object for method chaining.
495    */
496   public Value<T> set(T t) {
497      this.t = t;
498      if (nn(listener))
499         listener.onSet(t);
500      return this;
501   }
502
503   /**
504    * Sets the value only if the specified condition is <jk>true</jk>.
505    *
506    * <h5 class='section'>Example:</h5>
507    * <p class='bjava'>
508    *    Value&lt;String&gt; <jv>value</jv> = Value.<jsm>of</jsm>(<js>"old"</js>);
509    *    <jv>value</jv>.setIf(<jk>true</jk>, <js>"new"</js>);   <jc>// Sets to "new"</jc>
510    *    <jv>value</jv>.setIf(<jk>false</jk>, <js>"newer"</js>);  <jc>// Does nothing</jc>
511    *    <jsm>assertEquals</jsm>(<js>"new"</js>, <jv>value</jv>.get());
512    * </p>
513    *
514    * @param condition The condition to check.
515    * @param t The value to set if condition is <jk>true</jk>.
516    * @return This object.
517    */
518   public Value<T> setIf(boolean condition, T t) {
519      if (condition)
520         set(t);
521      return this;
522   }
523
524   /**
525    * Sets the value only if it is currently empty (<jk>null</jk>).
526    *
527    * <p>
528    * If the value is already set, this method does nothing.
529    *
530    * <h5 class='section'>Example:</h5>
531    * <p class='bjava'>
532    *    Value&lt;String&gt; <jv>value</jv> = Value.<jsm>empty</jsm>();
533    *    <jv>value</jv>.setIfEmpty(<js>"first"</js>);   <jc>// Sets value to "first"</jc>
534    *    <jv>value</jv>.setIfEmpty(<js>"second"</js>);  <jc>// Does nothing, value remains "first"</jc>
535    *    <jsm>assertEquals</jsm>(<js>"first"</js>, <jv>value</jv>.get());
536    * </p>
537    *
538    * @param t The new value. Can be <jk>null</jk>.
539    * @return This object for method chaining.
540    */
541   public Value<T> setIfEmpty(T t) {
542      if (isEmpty())
543         set(t);
544      return this;
545   }
546
547   @Override /* Overridden from Object */
548   public String toString() {
549      return "Value(" + t + ")";
550   }
551
552   /**
553    * Updates the value in-place using the specified function.
554    *
555    * <p>
556    * If the current value is <jk>null</jk>, this is a no-op.
557    *
558    * <h5 class='section'>Example:</h5>
559    * <p class='bjava'>
560    *    Value&lt;String&gt; <jv>value</jv> = Value.<jsm>of</jsm>(<js>"hello"</js>);
561    *    <jv>value</jv>.update(String::toUpperCase);
562    *    <jsm>assertEquals</jsm>(<js>"HELLO"</js>, <jv>value</jv>.get());
563    *
564    *    <jc>// No-op when null</jc>
565    *    Value&lt;String&gt; <jv>empty</jv> = Value.<jsm>empty</jsm>();
566    *    <jv>empty</jv>.update(String::toUpperCase);  <jc>// Does nothing</jc>
567    *    <jsm>assertNull</jsm>(<jv>empty</jv>.get());
568    * </p>
569    *
570    * @param updater The function to apply to the current value. Must not be <jk>null</jk>.
571    * @return This object.
572    */
573   public Value<T> update(Function<T,T> updater) {
574      if (nn(t))
575         set(updater.apply(t));
576      return this;
577   }
578}