AbstractCollectionDecorator.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.collection;

  18. import java.io.Serializable;
  19. import java.util.Collection;
  20. import java.util.Iterator;
  21. import java.util.Objects;
  22. import java.util.function.Predicate;

  23. /**
  24.  * Decorates another {@code Collection} to provide additional behavior.
  25.  * <p>
  26.  * Each method call made on this {@code Collection} is forwarded to the
  27.  * decorated {@code Collection}. This class is used as a framework on which
  28.  * to build to extensions such as synchronized and unmodifiable behavior. The
  29.  * main advantage of decoration is that one decorator can wrap any implementation
  30.  * of {@code Collection}, whereas sub-classing requires a new class to be
  31.  * written for each implementation.
  32.  * </p>
  33.  * <p>
  34.  * This implementation does not perform any special processing with
  35.  * {@link #iterator()}. Instead it simply returns the value from the
  36.  * wrapped collection. This may be undesirable, for example if you are trying
  37.  * to write an unmodifiable implementation it might provide a loophole.
  38.  * </p>
  39.  * <p>
  40.  * This implementation does not forward the hashCode and equals methods through
  41.  * to the backing object, but relies on Object's implementation. This is necessary
  42.  * to preserve the symmetry of equals. Custom definitions of equality are usually
  43.  * based on an interface, such as Set or List, so that the implementation of equals
  44.  * can cast the object being tested for equality to the custom interface.
  45.  * AbstractCollectionDecorator does not implement such custom interfaces directly;
  46.  * they are implemented only in subclasses. Therefore, forwarding equals would break
  47.  * symmetry, as the forwarding object might consider itself equal to the object being
  48.  * tested, but the reverse could not be true. This behavior is consistent with the
  49.  * JDK's collection wrappers, such as {@link java.util.Collections#unmodifiableCollection(Collection)}.
  50.  * Use an interface-specific subclass of AbstractCollectionDecorator, such as
  51.  * AbstractListDecorator, to preserve equality behavior, or override equals directly.
  52.  * </p>
  53.  *
  54.  * @param <E> the type of the elements in the collection
  55.  * @since 3.0
  56.  */
  57. public abstract class AbstractCollectionDecorator<E>
  58.         implements Collection<E>, Serializable {

  59.     /** Serialization version */
  60.     private static final long serialVersionUID = 6249888059822088500L;

  61.     /** The collection being decorated */
  62.     private Collection<E> collection;

  63.     /**
  64.      * Constructor only used in deserialization, do not use otherwise.
  65.      * @since 3.1
  66.      */
  67.     protected AbstractCollectionDecorator() {
  68.     }

  69.     /**
  70.      * Constructor that wraps (not copies).
  71.      *
  72.      * @param collection  the collection to decorate, must not be null
  73.      * @throws NullPointerException if the collection is null
  74.      */
  75.     protected AbstractCollectionDecorator(final Collection<E> collection) {
  76.         this.collection = Objects.requireNonNull(collection, "collection");
  77.     }

  78.     @Override
  79.     public boolean add(final E object) {
  80.         return decorated().add(object);
  81.     }

  82.     @Override
  83.     public boolean addAll(final Collection<? extends E> coll) {
  84.         return decorated().addAll(coll);
  85.     }

  86.     @Override
  87.     public void clear() {
  88.         decorated().clear();
  89.     }

  90.     @Override
  91.     public boolean contains(final Object object) {
  92.         return decorated().contains(object);
  93.     }

  94.     @Override
  95.     public boolean containsAll(final Collection<?> coll) {
  96.         return decorated().containsAll(coll);
  97.     }

  98.     /**
  99.      * Gets the collection being decorated.
  100.      * All access to the decorated collection goes via this method.
  101.      *
  102.      * @return the decorated collection
  103.      */
  104.     protected Collection<E> decorated() {
  105.         return collection;
  106.     }

  107.     @Override
  108.     public boolean isEmpty() {
  109.         return decorated().isEmpty();
  110.     }

  111.     @Override
  112.     public Iterator<E> iterator() {
  113.         return decorated().iterator();
  114.     }

  115.     @Override
  116.     public boolean remove(final Object object) {
  117.         return decorated().remove(object);
  118.     }

  119.     @Override
  120.     public boolean removeAll(final Collection<?> coll) {
  121.         return decorated().removeAll(coll);
  122.     }

  123.     /**
  124.      * @since 4.4
  125.      */
  126.     @Override
  127.     public boolean removeIf(final Predicate<? super E> filter) {
  128.         return decorated().removeIf(filter);
  129.     }

  130.     @Override
  131.     public boolean retainAll(final Collection<?> coll) {
  132.         return decorated().retainAll(coll);
  133.     }

  134.     /**
  135.      * Sets the collection being decorated.
  136.      * <p>
  137.      * <strong>NOTE:</strong> this method should only be used during deserialization
  138.      *
  139.      * @param collection  the decorated collection
  140.      */
  141.     protected void setCollection(final Collection<E> collection) {
  142.         this.collection = collection;
  143.     }

  144.     @Override
  145.     public int size() {
  146.         return decorated().size();
  147.     }

  148.     @Override
  149.     public Object[] toArray() {
  150.         return decorated().toArray();
  151.     }

  152.     @Override
  153.     public <T> T[] toArray(final T[] object) {
  154.         return decorated().toArray(object);
  155.     }

  156.     @Override
  157.     public String toString() {
  158.         return decorated().toString();
  159.     }

  160. }