Class Converter<A,B>

A function from A to B with an associated reverse function from B
to A; used for converting back and forth between different representations of the same
information.

Invertibility

The reverse operation may be a strict inverse (meaning that converter.reverse().convert(converter.convert(a)).equals(a) is always true). However, it is
very common (perhaps more common) for round-trip conversion to be lossy. Consider
an example round-trip using Doubles.stringConverter():

stringConverter().convert("1.00") returns the Double value 1.0

stringConverter().reverse().convert(1.0) returns the string "1.0" --
not the same string ("1.00") we started with

Note that it should still be the case that the round-tripped and original objects are
similar.

Nullability

A converter always converts null to null and non-null references to non-null
references. It would not make sense to consider null and a non-null reference to be
"different representations of the same information", since one is distinguishable from
missing information and the other is not. The convert(A) method handles this null
behavior for all converters; implementations of doForward(A) and doBackward(B) are
guaranteed to never be passed null, and must never return null.

Common ways to use

Convert between specific preset values using Maps.asConverter. For example, use this to create
a "fake" converter for a unit test. It is unnecessary (and confusing) to mock the
Converter type using a mocking framework.

doBackward

Returns a representation of b as an instance of type A. If b cannot be
converted, an unchecked exception (such as IllegalArgumentException) should be thrown.

Parameters:

b - the instance to convert; will never be null

Returns:

the converted instance; must not be null

Throws:

UnsupportedOperationException - if backward conversion is not implemented; this should be
very rare. Note that if backward conversion is not only unimplemented but
unimplementable (for example, consider a Converter<Chicken, ChickenNugget>),
then this is not logically a Converter at all, and should just implement Function.

equals

Most implementations will have no reason to override the behavior of Object.equals(java.lang.Object).
However, an implementation may also choose to return true whenever object is a
Converter that it considers interchangeable with this one. "Interchangeable"
typically means that Objects.equal(this.convert(a), that.convert(a)) is true for
all a of type A (and similarly for reverse). Note that a false
result from this method does not imply that the converters are known not to be
interchangeable.

from

Returns a converter based on existing forward and backward functions. Note that it is
unnecessary to create new classes implementing Function just to pass them in
here. Instead, simply subclass Converter and implement its doForward(A) and
doBackward(B) methods directly.

These functions will never be passed null and must not under any circumstances
return null. If a value cannot be converted, the function should throw an unchecked
exception (typically, but not necessarily, IllegalArgumentException).

The returned converter is serializable if both provided functions are.