/* * Copyright 2013 Cameron Beccario * * 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 net.nullschool.collect; import java.util.Collection; import java.util.Set; /** * 2013-02-15<p/> * * A persistent (i.e., immutable) {@link Set}. See a description of persistent data structures on * <a href="http://en.wikipedia.org/wiki/Persistent_data_structures">Wikipedia</a>.<p/> A ConstSet instance is * guaranteed to never visibly change. New elements can be added or removed using the {@link #with}, {@link #without}, * and related methods, which allocate a new instance if necessary while leaving the original instance unchanged.<p/> * * Because a ConstSet is effectively immutable, the {@link #add}, {@link #addAll}, {@link #remove}, * {@link #removeAll}, {@link #retainAll}, and {@link #clear} methods inherited from {@link Set} always throw * {@link UnsupportedOperationException}. They are marked <i>deprecated</i> to signify to the developer that they * should not be invoked. * * @param <E> the element type * * @author Cameron Beccario */ public interface ConstSet<E> extends Set<E>, ConstCollection<E> { /** * Returns a ConstSet containing the elements of this set plus the specified element if it is not already * contained in this set. No visible change to this set occurs. In this way, the {@code with} method may be * considered a factory method for creating new instances of ConstSet.<p/> * * Depending on the implementation, ConstSets may refuse to add the specified element. Well behaved * implementations should throw an exception detailing the reason for refusal, except in the case where this set * already contains the element. In that case, where the resulting set R would otherwise equal this set, * {@code R.equals(this)}, then the method may simply return this set, unchanged. * * @param e the element to add. * @return a ConstSet containing this set's elements conjoined with the specified element. * @throws ClassCastException if the element is of a type not suitable for this or the resulting set. * @throws NullPointerException if the element is null and either this or the resulting set does not allow nulls. * @throws IllegalArgumentException if some property of the element is not suitable for this or the resulting set. */ @Override ConstSet<E> with(E e); /** * Returns a ConstSet containing the elements of this set plus all the unique elements of the specified * collection. No visible change to this set occurs. In this way, the {@code withAll} method may be * considered a factory method for creating new instances of ConstSet.<p/> * * The effect of this call is equivalent to invoking {@link #with} for each element in the specified collection. * Depending on the implementation, ConstSets may refuse to add any of the specified elements. Well behaved * implementations should throw an exception detailing the reason for refusal, except in the case where this * set already contains any of the elements. In that case, where the resulting set R would otherwise equal this * set, {@code R.equals(this)}, then the method may simply return this set, unchanged. * * @param c the elements to conjoin with the elements in this set. * @return a ConstSet containing this set's elements plus the elements in the provided collection. * @throws ClassCastException if one of the elements is of a type not suitable for this or the resulting set. * @throws NullPointerException if the specified collection is null, or if one of its elements is null and either * this or the resulting set does not allow nulls. * @throws IllegalArgumentException if some property of an element in the specified collection is not suitable for * this or the resulting set. */ @Override ConstSet<E> withAll(Collection<? extends E> c); /** * Returns a ConstSet containing the elements of this collection minus the specified element. No visible * change to this set occurs. In this way, the {@code without} method may be considered a factory method * for creating new instances of ConstSet.<p/> * * If this set does not contain the specified element, i.e., if the resulting set R would otherwise equal this * set, {@code R.equals(this)}, then the method may simply return this set, unchanged. * * @param o the element to remove. * @return a ConstSet containing this set's elements minus the specified element. * @throws ClassCastException if the element is of a type not suitable for this set. * @throws NullPointerException if the element is null and this set does not allow null elements. */ @Override ConstSet<E> without(Object o); /** * Returns a ConstSet containing the elements of this set minus all the elements of the specified set. No visible * change to this set occurs. In this way, the {@code withoutAll} method may be considered a factory method for * creating new instances of ConstSet.<p/> * * The effect of this call is equivalent to invoking {@link #without} for each element in the specified * collection. If this set does not contain any of the elements, i.e., if the resulting set R would otherwise * equal this set, {@code R.equals(this)}, then the method may simply return this set, unchanged. * * @param c the elements to remove. * @return a ConstSet containing this set's elements minus the specified elements. * @throws ClassCastException if one of the specified elements is of a type not suitable for this set. * @throws NullPointerException if the specified collection is null, or if one its elements is null and this * set does not allow nulls. */ @Override ConstSet<E> withoutAll(Collection<?> c); // ================================================================================================================= // Mutation methods marked @Deprecated to signify they should not be invoked. /** * This method throws {@link UnsupportedOperationException}. * @deprecated see {@link #with} */ @Deprecated @Override boolean add(E e); /** * This method throws {@link UnsupportedOperationException}. * @deprecated see {@link #withAll} */ @Deprecated @Override boolean addAll(Collection<? extends E> c); /** * This method throws {@link UnsupportedOperationException}. * @deprecated see {@link #without} */ @Deprecated @Override boolean remove(Object o); /** * This method throws {@link UnsupportedOperationException}. * @deprecated see {@link #withoutAll} */ @Deprecated @Override boolean removeAll(Collection<?> c); /** * This method throws {@link UnsupportedOperationException}. * @deprecated retainAll is not supported. */ @Deprecated @Override boolean retainAll(Collection<?> c); /** * This method throws {@link UnsupportedOperationException}. * @deprecated see {@link #without} */ @Deprecated @Override void clear(); }