/* * Copyright 2016-present Facebook, Inc. * * 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.facebook.buck.util; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableListMultimap; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSortedMap; import com.google.common.collect.ImmutableSortedSet; import com.google.common.collect.Ordering; import java.util.Comparator; import java.util.function.Function; import java.util.stream.Collector; public final class MoreCollectors { private MoreCollectors() {} /** * Returns a {@code Collector} that builds an {@code ImmutableList}. * * <p>This {@code Collector} behaves similar to {@code * Collectors.collectingAndThen(Collectors.toList(), ImmutableList::copyOf)} but without building * the intermediate list. * * @param <T> the type of the input elements * @return a {@code Collector} that builds an {@code ImmutableList}. */ public static <T> Collector<T, ?, ImmutableList<T>> toImmutableList() { return Collector.<T, ImmutableList.Builder<T>, ImmutableList<T>>of( ImmutableList::builder, ImmutableList.Builder::add, (left, right) -> left.addAll(right.build()), ImmutableList.Builder::build); } /** * Returns a {@code Collector} that builds an {@code ImmutableSet}. * * <p>This {@code Collector} behaves similar to {@code * Collectors.collectingAndThen(Collectors.toList(), ImmutableSet::copyOf)} but without building * the intermediate list. * * @param <T> the type of the input elements * @return a {@code Collector} that builds an {@code ImmutableSet}. */ public static <T> Collector<T, ?, ImmutableSet<T>> toImmutableSet() { return Collector.<T, ImmutableSet.Builder<T>, ImmutableSet<T>>of( ImmutableSet::builder, ImmutableSet.Builder::add, (left, right) -> left.addAll(right.build()), ImmutableSet.Builder::build); } /** * Returns a {@code Collector} that builds an {@code ImmutableSortedSet}. * * <p>This {@code Collector} behaves similar to: {@code Collectors.collectingAndThen( * Collectors.toList(), list -> ImmutableSortedSet.copyOf(comparator, list)) } but without * building the intermediate list. * * @param <T> the type of the input elements * @return a {@code Collector} that builds an {@code ImmutableSortedSet}. */ public static <T extends Comparable<T>> Collector<T, ?, ImmutableSortedSet<T>> toImmutableSortedSet() { return Collector.of( () -> new ImmutableSortedSet.Builder<T>(Ordering.natural()), ImmutableSortedSet.Builder::add, (left, right) -> left.addAll(right.build()), ImmutableSortedSet.Builder::build); } /** * Returns a {@code Collector} that builds an {@code ImmutableSortedSet}. * * <p>This {@code Collector} behaves similar to: {@code Collectors.collectingAndThen( * Collectors.toList(), list -> ImmutableSortedSet.copyOf(comparator, list)) } but without * building the intermediate list. * * @param <T> the type of the input elements * @param ordering comparator used to order the elements. * @return a {@code Collector} that builds an {@code ImmutableSortedSet}. */ public static <T> Collector<T, ?, ImmutableSortedSet<T>> toImmutableSortedSet( Comparator<? super T> ordering) { return Collector.of( () -> new ImmutableSortedSet.Builder<T>(ordering), ImmutableSortedSet.Builder::add, (left, right) -> left.addAll(right.build()), ImmutableSortedSet.Builder::build); } /** * Returns a {@code Collector} that builds an {@code ImmutableMap}, whose keys and values are the * result of applying mapping functions to the input elements. * * <p>This {@code Collector} behaves similar to {@code * Collectors.collectingAndThen(Collectors.toMap(), ImmutableMap::copyOf)} but preserves iteration * order and does not build an intermediate map. * * @param <T> the type of the input elements * @param <K> the output type of the key mapping function * @param <U> the output type of the value mapping function * @param keyMapper a mapping function to produce keys * @param valueMapper a mapping function to produce values * @return a {@code Collector} that builds an {@code ImmutableMap}. */ public static <T, K, U> Collector<T, ?, ImmutableMap<K, U>> toImmutableMap( Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper) { return Collector.<T, ImmutableMap.Builder<K, U>, ImmutableMap<K, U>>of( ImmutableMap::builder, (builder, elem) -> builder.put(keyMapper.apply(elem), valueMapper.apply(elem)), (left, right) -> left.putAll(right.build()), ImmutableMap.Builder::build); } /** * Returns a {@code Collector} that builds an {@code ImmutableSortedMap}, whose keys and values * are the result of applying mapping functions to the input elements. * * <p>The built map uses the natural ordering for elements. * * <p>This {@code Collector} behaves similar to {@code * Collectors.collectingAndThen(Collectors.toMap(), ImmutableSortedMap::copyOf)} but does not * build an intermediate map. * * @param <T> the type of the input elements * @param <K> the output type of the key mapping function * @param <U> the output type of the value mapping function * @param keyMapper a mapping function to produce keys * @param valueMapper a mapping function to produce values * @return a {@code Collector} that builds an {@code ImmutableMap}. */ public static <T, K extends Comparable<?>, U> Collector<T, ?, ImmutableSortedMap<K, U>> toImmutableSortedMap( Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper) { return Collector.<T, ImmutableSortedMap.Builder<K, U>, ImmutableSortedMap<K, U>>of( ImmutableSortedMap::naturalOrder, (builder, elem) -> builder.put(keyMapper.apply(elem), valueMapper.apply(elem)), (left, right) -> left.putAll(right.build()), ImmutableSortedMap.Builder::build); } /** * Returns a {@code Collector} that builds an {@code ImmutableMultimap}, whose keys and values are * the result of applying mapping functions to the input elements. * * <p>This {@code Collector} behaves similar to {@code * Collectors.collectingAndThen(Collectors.toMap(), ImmutableMultimap::copyOf)} but preserves * iteration order and does not build an intermediate map. * * @param <T> the type of the input elements * @param <K> the output type of the key mapping function * @param <U> the output type of the value mapping function * @param keyMapper a mapping function to produce keys * @param valueMapper a mapping function to produce values * @return a {@code Collector} that builds an {@code ImmutableMultimap}. */ public static <T, K, U> Collector<T, ?, ImmutableMultimap<K, U>> toImmutableMultimap( Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper) { return Collector.<T, ImmutableMultimap.Builder<K, U>, ImmutableMultimap<K, U>>of( ImmutableListMultimap::builder, (builder, elem) -> builder.put(keyMapper.apply(elem), valueMapper.apply(elem)), (left, right) -> left.putAll(right.build()), ImmutableMultimap.Builder::build); } /** * Returns a {@code Collector} that builds an {@code ImmutableListMultimap}, whose keys and values * are the result of applying mapping functions to the input elements. * * <p>This {@code Collector} behaves similar to {@code * Collectors.collectingAndThen(Collectors.toMap(), ImmutableListMultimap::copyOf)} but preserves * iteration order and does not build an intermediate map. * * @param <T> the type of the input elements * @param <K> the output type of the key mapping function * @param <U> the output type of the value mapping function * @param keyMapper a mapping function to produce keys * @param valueMapper a mapping function to produce values * @return a {@code Collector} that builds an {@code ImmutableListMultimap}. */ public static <T, K, U> Collector<T, ?, ImmutableListMultimap<K, U>> toImmutableListMultimap( Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper) { return Collector.<T, ImmutableListMultimap.Builder<K, U>, ImmutableListMultimap<K, U>>of( ImmutableListMultimap::builder, (builder, elem) -> builder.put(keyMapper.apply(elem), valueMapper.apply(elem)), (left, right) -> left.putAll(right.build()), ImmutableListMultimap.Builder::build); } }