Interface VirtualField<T>

Type Parameters:
T - the value type of the variable
All Superinterfaces:
Consumer<T>, Supplier<T>
All Known Implementing Classes:
VirtualField.ReadOnly

public interface VirtualField<T> extends Supplier<T>, Consumer<T>
Reified field-like variable.

Comparison with Reflected Fields

Virtual fields differ from objects of class Field in several ways:

  • Need not refer to an actual field.
  • No runtime metadata.
  • Access is not dynamically bound.
  • The owner is bound at construction time.
  • Can optionally be read-only.

Getting and Setting

Getting the value of a virtual field is effected using the method get() (inherited from Supplier).

Virtual fields have serveral operations that deal with setting:

accept(T)
is a method that takes the new value, and returns nothing (inherited from Consumer).
swap(T)
is a method that takes the new value, and returns the old value (analogous to Map.put(K, V)).
modify(T)
is a method that takes the new value, and indicates change (analogous to Set.add(E)).
swapWith, modifyWith
are methods that take a function to compute the new value from the old one (analogous to Stream.map(java.util.function.Function<? super T, ? extends R>)).
computeIfAbsent(java.util.function.Supplier<? extends T>), computeIfPresent(java.util.function.Function<? super T, ? extends T>), merge(T,java.util.function.BiFunction<? super T,? super T,? extends T>)
make a virtual field behave like a single-place, keyless Map.

Setter Default Implementations

The setter variants can each be implemented in terms of one of the others. The default implementations take swap(T) as primitive and abstract. If, for some custom implementation, it is more natural to define one of modify(T) or accept(T) as primitive, then swap(T) can be defined in terms of that one, and get().

Aliasing

Having two distinct virtual fields does not guarantee that the underlying storage does not coincide. In fact, one may be some proxy or view of the other.

Thread Safety

Virtual fields are not inherently thread-safe.

  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Interface
    Description
    static class 
    Base class for virtual fields that cannot be set.
  • Method Summary

    Modifier and Type
    Method
    Description
    default void
    accept(T newValue)
    Sets a new value for this virtual field and forgets the old one (optional operation).
    Creates a virtual field that is a read-only proxy of this field.
    default T
    computeIfAbsent(Supplier<? extends T> supp)
    Sets a new value for this virtual field if the old value is null, and returns the new value.
    default T
    computeIfPresent(Function<? super T,? extends T> fun)
    Sets a new value for this virtual field based on the old value if it is non-null, and returns the new value.
    static <T> VirtualField.ReadOnly<T>
    constant(T value)
    Creates a virtual field that always has the given value.
    static <T> VirtualField<T>
    elementAt(List<T> list, int index)
    Creates a virtual field backed by a list element.
    static <K, T> VirtualField<T>
    elementAt(Map<K,T> map, K key)
    Creates a virtual field backed by a map element.
    static <T> VirtualField<T>
    elementAt(T[] array, int index)
    Creates a virtual field backed by an array element.
    get()
    Returns the current value of this virtual field.
    default VirtualField<T>
    guard(Predicate<? super T> admissible)
    Returns a virtual field backed by this field that admits only certain new values.
    default boolean
    Checks whether this virtual field is read-only.
    default T
    merge(T value, BiFunction<? super T,? super T,? extends T> fun)
    Sets a new value for this virtual field based on the old value if it is non-null, and a given value, and returns the new value.
    default boolean
    modify(T newValue)
    Sets a new value for this virtual field and indicates change (optional operation).
    default boolean
    modifyWith(Function<? super T,? extends T> fun)
    Sets a new value for this virtual field based on the old value, and indicates change.
    static <T> VirtualField.ReadOnly<T>
    readOnly(Supplier<? extends T> getter)
    Creates a virtual field that can be read using the given getter operation.
    static <T> VirtualField<T>
    Creates a virtual field with a new backing field that can be read and written.
    static <T> VirtualField<T>
    readWrite(Supplier<? extends T> getter, Consumer<? super T> setter)
    Creates a virtual field that can be read and written using the given getter and setter operations, respectively.
    static <T> VirtualField<T>
    readWrite(T initialValue)
    Creates a virtual field with a new backing field that can be read and written.
    swap(T newValue)
    Sets a new value for this virtual field and returns the old value (optional operation).
    default T
    swapWith(Function<? super T,? extends T> fun)
    Sets a new value for this virtual field based on the old value, and returns the old value.

    Methods inherited from interface java.util.function.Consumer

    andThen
  • Method Details

    • get

      T get()
      Returns the current value of this virtual field.
      Specified by:
      get in interface Supplier<T>
      Returns:
      the current value of this virtual field
    • isReadOnly

      default boolean isReadOnly()
      Checks whether this virtual field is read-only.

      The default implementation always returns false; subclasses may override to realize read-only virtual fields.

      Returns:
      false if the value can be set; true if the value cannot be set
    • asReadOnly

      default VirtualField.ReadOnly<T> asReadOnly()
      Creates a virtual field that is a read-only proxy of this field.
      Returns:
      a read-only virtual field from which the value can be gotten as from this field
    • swap

      T swap(T newValue)
      Sets a new value for this virtual field and returns the old value (optional operation).
      Returns:
      the old value of this virtual field
      Throws:
      UnsupportedOperationException - if this virtual field cannot be set
    • modify

      default boolean modify(T newValue)
      Sets a new value for this virtual field and indicates change (optional operation).
      Returns:
      true if the value has changed
      Throws:
      UnsupportedOperationException - if this virtual field cannot be set
    • accept

      default void accept(T newValue)
      Sets a new value for this virtual field and forgets the old one (optional operation).

      This method adds no functionality over swap(T) and modify(T), but just implements Supplier.

      Specified by:
      accept in interface Consumer<T>
      Throws:
      UnsupportedOperationException - if this virtual field cannot be set
    • swapWith

      default T swapWith(Function<? super T,? extends T> fun)
      Sets a new value for this virtual field based on the old value, and returns the old value.
      Parameters:
      fun - a function for computing the new value given the old one
      Returns:
      the old value of this virtual field
      Throws:
      NullPointerException - if fun is null
      UnsupportedOperationException - if this virtual field cannot be set
    • modifyWith

      default boolean modifyWith(Function<? super T,? extends T> fun)
      Sets a new value for this virtual field based on the old value, and indicates change.
      Parameters:
      fun - a function for computing the new value given the old one
      Returns:
      true if the value has changed
      Throws:
      NullPointerException - if fun is null
      UnsupportedOperationException - if this attribute cannot be set
    • computeIfAbsent

      default T computeIfAbsent(Supplier<? extends T> supp)
      Sets a new value for this virtual field if the old value is null, and returns the new value.
      Parameters:
      supp - used to compute the new value if the old value is null
      Returns:
      the old value of this virtual field if non-null, or otherwise the new value
      Throws:
      NullPointerException - if supp is null
      UnsupportedOperationException - if this virtual field cannot be set
      See Also:
    • computeIfPresent

      default T computeIfPresent(Function<? super T,? extends T> fun)
      Sets a new value for this virtual field based on the old value if it is non-null, and returns the new value.
      Parameters:
      fun - a function for computing the new value given the old, non-null one
      Returns:
      the old value of this virtual field if null, or otherwise the new value
      Throws:
      NullPointerException - if fun is null
      UnsupportedOperationException - if this attribute cannot be set
      See Also:
    • merge

      default T merge(T value, BiFunction<? super T,? super T,? extends T> fun)
      Sets a new value for this virtual field based on the old value if it is non-null, and a given value, and returns the new value. If the old value is null, it is simply replaced by the given one.
      Parameters:
      value - the given value
      fun - a function for computing the new value from the old, non-null value, and the given value
      Returns:
      the new value of this field; either the combination of the old and the given value or just the given one
      Throws:
      NullPointerException - if fun is null
      UnsupportedOperationException - if this attribute cannot be set
      See Also:
    • constant

      static <T> VirtualField.ReadOnly<T> constant(T value)
      Creates a virtual field that always has the given value.
      Type Parameters:
      T - the value type of the variable
      Parameters:
      value - the given value
      Returns:
      a virtual field that always has that value
    • readOnly

      static <T> VirtualField.ReadOnly<T> readOnly(Supplier<? extends T> getter)
      Creates a virtual field that can be read using the given getter operation.

      The created virtual field is read-only.

      Type Parameters:
      T - the value type of the variable
      Parameters:
      getter - an operation that reads the variable value
      Returns:
      a virtual field that can be read using getter
      Throws:
      NullPointerException - if getter is null
    • readWrite

      static <T> VirtualField<T> readWrite()
      Creates a virtual field with a new backing field that can be read and written.

      The field value is initialized to null.

      This is useful for giving anonymous classes and lambda expression write access to local variables.

      Returns:
      a virtual field with a new backing field
    • readWrite

      static <T> VirtualField<T> readWrite(T initialValue)
      Creates a virtual field with a new backing field that can be read and written.

      This is useful for giving anonymous classes and lambda expression write access to local variables.

      Parameters:
      initialValue - the initial field value
      Returns:
      a virtual field with a new backing field
    • readWrite

      static <T> VirtualField<T> readWrite(Supplier<? extends T> getter, Consumer<? super T> setter)
      Creates a virtual field that can be read and written using the given getter and setter operations, respectively.
      Type Parameters:
      T - the value type of the variable
      Parameters:
      getter - an operation that reads the variable value
      setter - an operation that writes the variable value
      Returns:
      a virtual field that can be read using getter, and written using setter
      Throws:
      NullPointerException - if getter or setter is null
    • elementAt

      static <T> VirtualField<T> elementAt(T[] array, int index)
      Creates a virtual field backed by an array element.

      The length of an array is fixed. Hence a check that index is a valid index in array is performed eagerly at construction time.

      Type Parameters:
      T - the value type of the variable
      Parameters:
      array - the backing array
      index - the selected index
      Returns:
      a virtual field backed by the element array[index]
      Throws:
      NullPointerException - if array is null
      ArrayIndexOutOfBoundsException - if index is out of bounds in array
    • elementAt

      static <T> VirtualField<T> elementAt(List<T> list, int index)
      Creates a virtual field backed by a list element.

      The length of a list is variable. Hence checks that index is a valid index in list is performed lazily at use time.

      Type Parameters:
      T - the value type of the variable
      Parameters:
      list - the backing list
      index - the selected index
      Returns:
      a virtual field backed by the element at index in list
      Throws:
      NullPointerException - if list is null
    • elementAt

      static <K, T> VirtualField<T> elementAt(Map<K,T> map, K key)
      Creates a virtual field backed by a map element.

      All keys of the correct type are valid in a map; the use of the null key is discouraged, because not all maps support it.

      Type Parameters:
      K - the key type of the backing map
      T - the value type of the variable
      Parameters:
      map - the backing map
      key - the selected key
      Returns:
      a virtual field backed by the element at key in list
      Throws:
      NullPointerException - if map is null
    • guard

      default VirtualField<T> guard(Predicate<? super T> admissible)
      Returns a virtual field backed by this field that admits only certain new values.

      For read-only virtual fields, there is no inadmissible setting to prevent, and hence the backing field itself is returned. For writable virtual fields, a proxy is created.

      The proxy does not prevent inadmissible results from arising by other means, such as being present since before its construction, or being set directly on the backing field, circumventing the proxy.

      Parameters:
      admissible - a check whether some value is admissible
      Returns:
      this for read-only fields; otherwise a virtual field from which the value of this virtual field can be gotten, but which can be set only to admissible values (attempting to set inadmissible values will cause IllegalArgumentException)
      Throws:
      NullPointerException - if admissible is null