Interface Both<A,B>

Functional Interface:
This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference.

@FunctionalInterface public interface Both<A,B>
Represents two unrelated or loosely-related things of type A and B.

Usually used as the return type of a function that needs to return two things. For example:


 first('=')
     .split("k=v")             // BiOptional<String, String>
     .orElseThrow(...)         // Both<String, String>
     .andThen(KeyValue::new);  // KeyValue
 
Or:

 import static com.google.mu.util.stream.MoreCollectors.partitioningBy;

 contacts.stream()
     .collect(partitioningBy(Contact::isPrimary, toOptional(), toImmutableList()))
     .andThen((primary, secondaries) -> ...);
 ...
 

If you have a stream of Both objects, the following turns it into a BiStream:


 BiStream<String, String> keyValues =
     BiStream.from(
         first(',')
             .repeatedly()
             .split("k1=v1,k2=v2,k3=v3")
             .map(s -> first('=').split(s).orElseThrow(...)));
 
Or in a single chained expression:

 import static com.google.mu.util.stream.BiStream.toBiStream;

 BiStream<String, String> keyValues =
     first(',')
         .repeatedly()
         .split("k1=v1,k2=v2,k3=v3")
         .collect(toBiStream(s -> first('=').split(s).orElseThrow(...)));
 

A stream of Both can also be collected using a BiCollector:


 import static com.google.mu.util.stream.MoreStreams.mapping;

 ImmutableListMultimap<String, String> keyValues =
     first(',')
         .repeatedly()
         .split("k1=v1,k2=v2,k3=v3")
         .collect(
             mapping(
                 s -> first('=').split(s).orElseThrow(...),
                 toImmutableListMultimap()));
 

Intended as a short-lived intermediary type in a fluent expression (e.g. from MoreCollectors.partitioningBy(java.util.function.Predicate<? super E>, java.util.stream.Collector<E, ?, R>), Substring.Pattern.split(java.lang.CharSequence)), it's expected that you can either chain fluently using andThen(java.util.function.BiFunction<? super A, ? super B, T>), filter(java.util.function.BiPredicate<? super A, ? super B>), or directly pass it to common libraries without needing to extract the two values. If you really have to extract the two values individually though, consider using toEntry() and then call the Map.Entry.getKey() and Map.Entry.getValue() methods to access them. For example:


 import static com.google.mu.util.stream.MoreCollectors.partitioningBy;

 var primaryAndSecondaries =
     contacts.stream()
         .collect(partitioningBy(Contact::isPrimary, toOptional(), toImmutableList()))
         .toEntry();
 Optional<Contact> primary = primaryAndSecondaries.getKey();
 ImmutableList<Contact> secondaries = primaryAndSecondaries.getValue();
 ...
 
Since:
5.1
  • Method Summary

    Modifier and Type
    Method
    Description
    <T> T
    andThen(BiFunction<? super A,? super B,T> mapper)
    Applies the mapper function with this pair of two things as arguments.
    default BiOptional<A,B>
    filter(BiPredicate<? super A,? super B> condition)
    If the pair matches() condition, returns a BiOptional containing the pair, or else returns empty.
    default boolean
    matches(BiPredicate<? super A,? super B> condition)
    Returns true if the pair matches condition.
    static <A, B> Both<A,B>
    of(A a, B b)
    Returns an instance with both a and b.
    default Both<A,B>
    peek(BiConsumer<? super A,? super B> consumer)
    Invokes consumer with this pair and returns this object as is.
    default BiOptional<A,B>
    skipIf(BiPredicate<? super A,? super B> predicate)
    If the pair matches predicate, it's skipped (returns empty).
    default Map.Entry<A,B>
    Returns an immutable Map.Entry holding the pair of values.
  • Method Details

    • of

      static <A, B> Both<A,B> of(A a, B b)
      Returns an instance with both a and b.
      Since:
      5.8
    • andThen

      <T> T andThen(BiFunction<? super A,? super B,T> mapper)
      Applies the mapper function with this pair of two things as arguments.
      Throws:
      NullPointerException - if mapper is null
    • filter

      default BiOptional<A,B> filter(BiPredicate<? super A,? super B> condition)
      If the pair matches() condition, returns a BiOptional containing the pair, or else returns empty.
      Throws:
      NullPointerException - if condition is null, or if condition matches but either value in this pair is null
    • skipIf

      default BiOptional<A,B> skipIf(BiPredicate<? super A,? super B> predicate)
      If the pair matches predicate, it's skipped (returns empty).
      Throws:
      NullPointerException - if predicate is null
      Since:
      6.6
    • matches

      default boolean matches(BiPredicate<? super A,? super B> condition)
      Returns true if the pair matches condition.
      Throws:
      NullPointerException - if condition is null
    • peek

      default Both<A,B> peek(BiConsumer<? super A,? super B> consumer)
      Invokes consumer with this pair and returns this object as is.
      Throws:
      NullPointerException - if consumer is null
    • toEntry

      default Map.Entry<A,B> toEntry()
      Returns an immutable Map.Entry holding the pair of values.
      Since:
      6.5