Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright (C) 2008 The Guava Authors
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   * http://www.apache.org/licenses/LICENSE-2.0
   *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 package com.google.common.base;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 
 
 
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 com.google.common.primitives.Doubles.stringConverter():

  1. stringConverter().convert("1.00") returns the Double value 1.0
  2. 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(java.lang.Object) method handles this null behavior for all converters; implementations of doForward(java.lang.Object) and doBackward(java.lang.Object) are guaranteed to never be passed null, and must never return null.

Common ways to use

Getting a converter:

Using a converter:

  • Convert one instance in the "forward" direction using converter.convert(a).
  • Convert multiple instances "forward" using converter.convertAll(as).
  • Convert in the "backward" direction using converter.reverse().convert(b) or converter.reverse().convertAll(bs).
  • Use converter or converter.reverse() anywhere a Function is accepted
  • Do not call doForward(java.lang.Object) or doBackward(java.lang.Object) directly; these exist only to be overridden.

Author(s):
Mike Ward
Kurt Alfred Kluever
Gregory Kick
Since:
16.0
 
 public abstract class Converter<A, B> implements Function<A, B> {
   private final boolean handleNullAutomatically;
 
   // We lazily cache the reverse view to avoid allocating on every call to reverse().
   private transient Converter<B, A> reverse;

  
Constructor for use by subclasses.
  protected Converter() {
    this(true);
  }

  
Constructor used only by LegacyConverter to suspend automatic null-handling.
  Converter(boolean handleNullAutomatically) {
    this. = handleNullAutomatically;
  }
  // SPI methods (what subclasses must implement)

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

Parameters:
a the instance to convert; will never be null
Returns:
the converted instance; must not be null
  protected abstract B doForward(A a);

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

Parameters:
b the instance to convert; will never be null
Returns:
the converted instance; must not be null
Throws:
java.lang.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.
  protected abstract A doBackward(B b);
  // API (consumer-side) methods

  
Returns a representation of a as an instance of type B.

Returns:
the converted value; is null if and only if a is null
  public final B convert(@Nullable A a) {
    return correctedDoForward(a);
  }
      // TODO(kevinb): we shouldn't be checking for a null result at runtime. Assert?
      return a == null ? null : checkNotNull(doForward(a));
    } else {
      return doForward(a);
    }
  }
      // TODO(kevinb): we shouldn't be checking for a null result at runtime. Assert?
      return b == null ? null : checkNotNull(doBackward(b));
    } else {
      return doBackward(b);
    }
  }

  
Returns an iterable that applies convert to each element of fromIterable. The conversion is done lazily.

The returned iterable's iterator supports remove() if the input iterator does. After a successful remove() call, fromIterable no longer contains the corresponding element.

  public Iterable<B> convertAll(final Iterable<? extends A> fromIterable) {
    checkNotNull(fromIterable"fromIterable");
    return new Iterable<B>() {
      @Override public Iterator<B> iterator() {
        return new Iterator<B>() {
          private final Iterator<? extends A> fromIterator = fromIterable.iterator();
          @Override
          public boolean hasNext() {
            return .hasNext();
          }
          @Override
          public B next() {
            return convert(.next());
          }
          @Override
          public void remove() {
            .remove();
          }
        };
      }
    };
  }

  
Returns the reversed view of this converter, which converts this.convert(a) back to a value roughly equivalent to a.

The returned converter is serializable if this converter is.

  // TODO(user): Make this method final
  public Converter<B, A> reverse() {
    Converter<B, A> result = ;
    return (result == null) ?  = new ReverseConverter<A, B>(this) : result;
  }
  private static final class ReverseConverter<A, B>
      extends Converter<B, A> implements Serializable {
    final Converter<A, B> original;
    ReverseConverter(Converter<A, B> original) {
      this. = original;
    }
    /*
     * These gymnastics are a little confusing. Basically this class has neither legacy nor
     * non-legacy behavior; it just needs to let the behavior of the backing converter shine
     * through. So, we override the correctedDo* methods, after which the do* methods should never
     * be reached.
     */
    @Override
    protected A doForward(B b) {
      throw new AssertionError();
    }
    @Override
    protected B doBackward(A a) {
      throw new AssertionError();
    }
    @Override
    @Nullable
    A correctedDoForward(@Nullable B b) {
      return .correctedDoBackward(b);
    }
    @Override
    @Nullable
    B correctedDoBackward(@Nullable A a) {
      return .correctedDoForward(a);
    }
    @Override
    public Converter<A, B> reverse() {
      return ;
    }
    @Override
    public boolean equals(@Nullable Object object) {
      if (object instanceof ReverseConverter) {
        ReverseConverter<?, ?> that = (ReverseConverter<?, ?>) object;
        return this..equals(that.original);
      }
      return false;
    }
    @Override
    public int hashCode() {
      return ~.hashCode();
    }
    @Override
    public String toString() {
      return  + ".reverse()";
    }
    private static final long serialVersionUID = 0L;
  }

  
Returns a converter whose convert method applies secondConverter to the result of this converter. Its reverse method applies the converters in reverse order.

The returned converter is serializable if this converter and secondConverter are.

  public final <C> Converter<A, C> andThen(Converter<B, C> secondConverter) {
    return doAndThen(secondConverter);
  }

  
Package-private non-final implementation of andThen() so only we can override it.
  <C> Converter<A, C> doAndThen(Converter<B, C> secondConverter) {
    return new ConverterComposition<A, B, C>(thischeckNotNull(secondConverter));
  }
  private static final class ConverterComposition<A, B, C>
      extends Converter<A, C> implements Serializable {
    final Converter<A, B> first;
    final Converter<B, C> second;
    ConverterComposition(Converter<A, B> firstConverter<B, C> second) {
      this. = first;
      this. = second;
    }
    /*
     * These gymnastics are a little confusing. Basically this class has neither legacy nor
     * non-legacy behavior; it just needs to let the behaviors of the backing converters shine
     * through (which might even differ from each other!). So, we override the correctedDo* methods,
     * after which the do* methods should never be reached.
     */
    @Override
    protected C doForward(A a) {
      throw new AssertionError();
    }
    @Override
    protected A doBackward(C c) {
      throw new AssertionError();
    }
    @Override
    @Nullable
    C correctedDoForward(@Nullable A a) {
    }
    @Override
    @Nullable
    A correctedDoBackward(@Nullable C c) {
    }
    @Override
    public boolean equals(@Nullable Object object) {
      if (object instanceof ConverterComposition) {
        ConverterComposition<?, ?, ?> that = (ConverterComposition<?, ?, ?>) object;
        return this..equals(that.first)
            && this..equals(that.second);
      }
      return false;
    }
    @Override
    public int hashCode() {
      return 31 * .hashCode() + .hashCode();
    }
    @Override
    public String toString() {
      return  + ".andThen(" +  + ")";
    }
    private static final long serialVersionUID = 0L;
  }

  

Deprecated:
Provided to satisfy the Function interface; use convert(java.lang.Object) instead.
  public final B apply(@Nullable A a) {
    return convert(a);
  }

  
Indicates whether another object is equal to this converter.

Most implementations will have no reason to override the behavior of java.lang.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.

  public boolean equals(@Nullable Object object) {
    return super.equals(object);
  }
  // Static converters

  
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(java.lang.Object) and doBackward(java.lang.Object) 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, java.lang.IllegalArgumentException).

The returned converter is serializable if both provided functions are.

Since:
17.0
  public static <A, B> Converter<A, B> from(
      Function<? super A, ? extends B> forwardFunction,
      Function<? super B, ? extends A> backwardFunction) {
    return new FunctionBasedConverter<A, B>(forwardFunctionbackwardFunction);
  }
  private static final class FunctionBasedConverter<A, B>
      extends Converter<A, B> implements Serializable {
    private final Function<? super A, ? extends B> forwardFunction;
    private final Function<? super B, ? extends A> backwardFunction;
    private FunctionBasedConverter(
        Function<? super A, ? extends B> forwardFunction,
        Function<? super B, ? extends A> backwardFunction) {
      this. = checkNotNull(forwardFunction);
      this. = checkNotNull(backwardFunction);
    }
    @Override
    protected B doForward(A a) {
      return .apply(a);
    }
    @Override
    protected A doBackward(B b) {
      return .apply(b);
    }
    @Override
    public boolean equals(@Nullable Object object) {
      if (object instanceof FunctionBasedConverter) {
        FunctionBasedConverter<?, ?> that = (FunctionBasedConverter<?, ?>) object;
        return this..equals(that.forwardFunction)
            && this..equals(that.backwardFunction);
      }
      return false;
    }
    @Override
    public int hashCode() {
      return .hashCode() * 31 + .hashCode();
    }
    @Override
    public String toString() {
      return "Converter.from(" +  + ", " +  + ")";
    }
  }

  
Returns a serializable converter that always converts or reverses an object to itself.
  @SuppressWarnings("unchecked"// implementation is "fully variant"
  public static <T> Converter<T, T> identity() {
  }

  
A converter that always converts or reverses an object to itself. Note that T is now a "pass-through type".
  private static final class IdentityConverter<T> extends Converter<T, T> implements Serializable {
    static final IdentityConverter INSTANCE = new IdentityConverter();
    @Override
    protected T doForward(T t) {
      return t;
    }
    @Override
    protected T doBackward(T t) {
      return t;
    }
    @Override
    public IdentityConverter<T> reverse() {
      return this;
    }
    @Override
    <S> Converter<T, S> doAndThen(Converter<T, S> otherConverter) {
      return checkNotNull(otherConverter"otherConverter");
    }
    /*
     * We *could* override convertAll() to return its input, but it's a rather pointless
     * optimization and opened up a weird type-safety problem.
     */
    @Override
    public String toString() {
      return "Converter.identity()";
    }
    private Object readResolve() {
      return ;
    }
    private static final long serialVersionUID = 0L;
  }
New to GrepCode? Check out our FAQ X