TransformedSet.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.apache.commons.collections4.set;

  18. import java.util.Set;

  19. import org.apache.commons.collections4.Transformer;
  20. import org.apache.commons.collections4.collection.TransformedCollection;

  21. /**
  22.  * Decorates another {@code Set} to transform objects that are added.
  23.  * <p>
  24.  * The add methods are affected by this class.
  25.  * Thus objects must be removed or searched for using their transformed form.
  26.  * For example, if the transformation converts Strings to Integers, you must
  27.  * use the Integer form to remove objects.
  28.  * </p>
  29.  * <p>
  30.  * This class is Serializable from Commons Collections 3.1.
  31.  * </p>
  32.  *
  33.  * @param <E> the type of the elements in this set
  34.  * @since 3.0
  35.  */
  36. public class TransformedSet<E> extends TransformedCollection<E> implements Set<E> {

  37.     /** Serialization version */
  38.     private static final long serialVersionUID = 306127383500410386L;

  39.     /**
  40.      * Factory method to create a transforming set that will transform
  41.      * existing contents of the specified set.
  42.      * <p>
  43.      * If there are any elements already in the set being decorated, they
  44.      * will be transformed by this method.
  45.      * Contrast this with {@link #transformingSet(Set, Transformer)}.
  46.      *
  47.      * @param <E> the element type
  48.      * @param set  the set to decorate, must not be null
  49.      * @param transformer  the transformer to use for conversion, must not be null
  50.      * @return a new transformed set
  51.      * @throws NullPointerException if set or transformer is null
  52.      * @since 4.0
  53.      */
  54.     public static <E> Set<E> transformedSet(final Set<E> set, final Transformer<? super E, ? extends E> transformer) {
  55.         final TransformedSet<E> decorated = new TransformedSet<>(set, transformer);
  56.         if (!set.isEmpty()) {
  57.             @SuppressWarnings("unchecked") // set is type E
  58.             final E[] values = (E[]) set.toArray(); // NOPMD - false positive for generics
  59.             set.clear();
  60.             for (final E value : values) {
  61.                 decorated.decorated().add(transformer.apply(value));
  62.             }
  63.         }
  64.         return decorated;
  65.     }

  66.     /**
  67.      * Factory method to create a transforming set.
  68.      * <p>
  69.      * If there are any elements already in the set being decorated, they
  70.      * are NOT transformed.
  71.      * Contrast this with {@link #transformedSet(Set, Transformer)}.
  72.      *
  73.      * @param <E> the element type
  74.      * @param set  the set to decorate, must not be null
  75.      * @param transformer  the transformer to use for conversion, must not be null
  76.      * @return a new transformed set
  77.      * @throws NullPointerException if set or transformer is null
  78.      * @since 4.0
  79.      */
  80.     public static <E> TransformedSet<E> transformingSet(final Set<E> set,
  81.             final Transformer<? super E, ? extends E> transformer) {
  82.         return new TransformedSet<>(set, transformer);
  83.     }

  84.     /**
  85.      * Constructor that wraps (not copies).
  86.      * <p>
  87.      * If there are any elements already in the set being decorated, they
  88.      * are NOT transformed.
  89.      *
  90.      * @param set  the set to decorate, must not be null
  91.      * @param transformer  the transformer to use for conversion, must not be null
  92.      * @throws NullPointerException if set or transformer is null
  93.      */
  94.     protected TransformedSet(final Set<E> set, final Transformer<? super E, ? extends E> transformer) {
  95.         super(set, transformer);
  96.     }

  97.     @Override
  98.     public boolean equals(final Object object) {
  99.         return object == this || decorated().equals(object);
  100.     }

  101.     @Override
  102.     public int hashCode() {
  103.         return decorated().hashCode();
  104.     }

  105. }