1 /* 2 * Copyright (C) 2013 The Dagger Authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package dagger.internal.codegen.extension; 18 19 import static java.util.stream.Collectors.collectingAndThen; 20 import static java.util.stream.Collectors.toList; 21 22 import com.google.common.collect.ImmutableList; 23 import com.google.common.collect.ImmutableMap; 24 import com.google.common.collect.ImmutableSet; 25 import com.google.common.collect.ImmutableSetMultimap; 26 import com.google.common.collect.Maps; 27 import java.util.Collection; 28 import java.util.EnumSet; 29 import java.util.Map; 30 import java.util.Optional; 31 import java.util.function.Function; 32 import java.util.stream.Collector; 33 import java.util.stream.Collectors; 34 import java.util.stream.Stream; 35 import java.util.stream.StreamSupport; 36 37 /** Utilities for streams. */ 38 public final class DaggerStreams { 39 40 /** 41 * Returns a {@link Collector} that accumulates the input elements into a new {@link 42 * ImmutableList}, in encounter order. 43 */ 44 // TODO(b/68008628): Use ImmutableList.toImmutableList(). toImmutableList()45 public static <T> Collector<T, ?, ImmutableList<T>> toImmutableList() { 46 return collectingAndThen(toList(), ImmutableList::copyOf); 47 } 48 49 /** 50 * Returns a {@link Collector} that accumulates the input elements into a new {@link 51 * ImmutableSet}, in encounter order. 52 */ 53 // TODO(b/68008628): Use ImmutableSet.toImmutableSet(). toImmutableSet()54 public static <T> Collector<T, ?, ImmutableSet<T>> toImmutableSet() { 55 return collectingAndThen(toList(), ImmutableSet::copyOf); 56 } 57 58 /** 59 * Returns a {@link Collector} that accumulates elements into an {@code ImmutableMap} whose keys 60 * and values are the result of applying the provided mapping functions to the input elements. 61 * Entries appear in the result {@code ImmutableMap} in encounter order. 62 */ 63 // TODO(b/68008628): Use ImmutableMap.toImmutableMap(). toImmutableMap( Function<? super T, K> keyMapper, Function<? super T, V> valueMapper)64 public static <T, K, V> Collector<T, ?, ImmutableMap<K, V>> toImmutableMap( 65 Function<? super T, K> keyMapper, Function<? super T, V> valueMapper) { 66 return Collectors.mapping( 67 value -> Maps.immutableEntry(keyMapper.apply(value), valueMapper.apply(value)), 68 Collector.of( 69 ImmutableMap::builder, 70 (ImmutableMap.Builder<K, V> builder, Map.Entry<K, V> entry) -> builder.put(entry), 71 (left, right) -> left.putAll(right.build()), 72 ImmutableMap.Builder::build)); 73 } 74 75 /** 76 * Returns a {@link Collector} that accumulates elements into an {@code ImmutableSetMultimap} 77 * whose keys and values are the result of applying the provided mapping functions to the input 78 * elements. Entries appear in the result {@code ImmutableSetMultimap} in encounter order. 79 */ 80 // TODO(b/68008628): Use ImmutableSetMultimap.toImmutableSetMultimap(). toImmutableSetMultimap( Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends V> valueMapper)81 public static <T, K, V> Collector<T, ?, ImmutableSetMultimap<K, V>> toImmutableSetMultimap( 82 Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends V> valueMapper) { 83 return Collectors.mapping( 84 value -> Maps.immutableEntry(keyMapper.apply(value), valueMapper.apply(value)), 85 Collector.of( 86 ImmutableSetMultimap::builder, 87 (ImmutableSetMultimap.Builder<K, V> builder, Map.Entry<K, V> entry) -> 88 builder.put(entry), 89 (left, right) -> left.putAll(right.build()), 90 ImmutableSetMultimap.Builder::build)); 91 } 92 93 /** 94 * Returns a function from {@link Object} to {@code Stream<T>}, which returns a stream containing 95 * its input if its input is an instance of {@code T}. 96 * 97 * <p>Use as an argument to {@link Stream#flatMap(Function)}: 98 * 99 * <pre>{@code Stream<Bar>} barStream = fooStream.flatMap(instancesOf(Bar.class));</pre> 100 */ instancesOf(Class<T> to)101 public static <T> Function<Object, Stream<T>> instancesOf(Class<T> to) { 102 return f -> to.isInstance(f) ? Stream.of(to.cast(f)) : Stream.empty(); 103 } 104 105 /** Returns a stream of all values of the given {@code enumType}. */ valuesOf(Class<E> enumType)106 public static <E extends Enum<E>> Stream<E> valuesOf(Class<E> enumType) { 107 return EnumSet.allOf(enumType).stream(); 108 } 109 110 /** 111 * A function that you can use to extract the present values from a stream of {@link Optional}s. 112 * 113 * <pre>{@code 114 * Set<Foo> foos = 115 * optionalFoos() 116 * .flatMap(DaggerStreams.presentValues()) 117 * .collect(toSet()); 118 * }</pre> 119 */ presentValues()120 public static <T> Function<Optional<T>, Stream<T>> presentValues() { 121 return optional -> optional.map(Stream::of).orElse(Stream.empty()); 122 } 123 124 /** 125 * Returns a sequential {@link Stream} of the contents of {@code iterable}, delegating to {@link 126 * Collection#stream} if possible. 127 */ stream(Iterable<T> iterable)128 public static <T> Stream<T> stream(Iterable<T> iterable) { 129 return (iterable instanceof Collection) 130 ? ((Collection<T>) iterable).stream() 131 : StreamSupport.stream(iterable.spliterator(), false); 132 } 133 DaggerStreams()134 private DaggerStreams() {} 135 } 136