guava icon indicating copy to clipboard operation
guava copied to clipboard

Consider avoiding the use of a pre-sized builder for the `FilteredCollection` in `Maps#uniqueIndex`

Open oksana-evs opened this issue 2 years ago • 1 comments

If values is a Collection, a presized builder is used in Maps#uniqueIndex (the change was introduced in this commit)

  @CanIgnoreReturnValue
  public static <K, V> ImmutableMap<K, V> uniqueIndex(
      Iterable<V> values, Function<? super V, K> keyFunction) {
    if (values instanceof Collection) {
      return uniqueIndex(
          values.iterator(),
          keyFunction,
          ImmutableMap.builderWithExpectedSize(((Collection<?>) values).size()));
    }
    return uniqueIndex(values.iterator(), keyFunction);
  }

However, for FilteredCollection, calling size() results in applying the predicate to all the elements of the unfiltered collection (link)

    @Override
    public int size() {
      int size = 0;
      for (E e : unfiltered) {
        if (predicate.apply(e)) {
          size++;
        }
      }
      return size;
    }

To prevent applying the predicate an additional time , presized builder should not be used if values is a FilteredCollection or FilteredMultimapValues

oksana-evs avatar Jul 14 '23 08:07 oksana-evs

The suggested fix is implemented in this pull request: https://github.com/PicnicSupermarket/guava/pull/27

oksana-evs avatar Jul 17 '23 14:07 oksana-evs