Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GROOVY-6944: Add immutable collections #482

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ dependencies {
exclude(group: 'jmock', module: 'jmock')
}
compile files("lib/openbeans-1.0.jar")
compile files("lib/pcollections-2.2.0-SNAPSHOT.jar")
compile "org.fusesource.jansi:jansi:$jansiVersion"
compile("org.apache.ivy:ivy:$ivyVersion") {
transitive = false
Expand Down
Binary file added lib/pcollections-2.2.0-SNAPSHOT.jar
Binary file not shown.
4 changes: 2 additions & 2 deletions src/main/groovy/transform/Immutable.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
* <li>{@code Date}s, {@code Cloneable}s and arrays are defensively copied on the way in (constructor) and out (getters).
* Arrays and {@code Cloneable} objects use the {@code clone} method. For your own classes,
* it is up to you to define this method and use deep cloning if appropriate.
* <li>{@code Collection}s and {@code Map}s are wrapped by immutable wrapper classes (but not deeply cloned!).
* <li>{@code Collection}s and {@code Map}s are wrapped by unmodifiable wrapper classes (but not deeply cloned!).
* Attempts to update them will result in an {@code UnsupportedOperationException}.
* <li>Fields that are enums or other {@code @Immutable} classes are allowed but for an
* otherwise possible mutable property type, an error is thrown.
Expand Down Expand Up @@ -101,7 +101,7 @@
* it is up to you to define this method and use deep cloning if appropriate.
* </li>
* <li>
* As outlined above, {@code Collection}s and {@code Map}s are wrapped by immutable wrapper classes (but not deeply cloned!).
* As outlined above, {@code Collection}s and {@code Map}s are wrapped by unmodifiable wrapper classes (but not deeply cloned!).
* </li>
* <li>
* Currently {@code BigInteger} and {@code BigDecimal} are deemed immutable but see:
Expand Down
88 changes: 88 additions & 0 deletions src/main/groovy/util/immutable/ImmutableCollection.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* Copyright 2003-2014 the original author or authors.
*
* 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 groovy.util.immutable;

import java.util.Collection;

/**
* An immutable and persistent collection of elements of type E.
*
* @author harold
* @author Yu Kobayashi
* @since 2.4.0
*/
public interface ImmutableCollection<E> extends Collection<E> {
/**
* @param element an element to append
* @return a collection which contains the element and all of the elements of this
*/
ImmutableCollection<E> plus(E element);

/**
* @param iterable elements to append
* @return a collection which contains all of the elements of iterable and this
*/
ImmutableCollection<E> plus(Iterable<? extends E> iterable);

/**
* @param element an element to remove
* @return this with a single instance of the element removed, if the element is in this collection
*/
ImmutableCollection<E> minus(Object element);

/**
* @param iterable elements to remove
* @return this with all elements of the iterable completely removed
*/
ImmutableCollection<E> minus(Iterable<?> iterable);

/**
* Always throws {@link UnsupportedOperationException}.
*/
@Deprecated
boolean add(E o);

/**
* Always throws {@link UnsupportedOperationException}.
*/
@Deprecated
boolean remove(Object o);

/**
* Always throws {@link UnsupportedOperationException}.
*/
@Deprecated
boolean addAll(Collection<? extends E> c);

/**
* Always throws {@link UnsupportedOperationException}.
*/
@Deprecated
boolean removeAll(Collection<?> c);

/**
* Always throws {@link UnsupportedOperationException}.
*/
@Deprecated
boolean retainAll(Collection<?> c);

/**
* Always throws {@link UnsupportedOperationException}.
*/
@Deprecated
void clear();
}
129 changes: 129 additions & 0 deletions src/main/groovy/util/immutable/ImmutableCollections.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
/*
* Copyright 2003-2014 the original author or authors.
*
* 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 groovy.util.immutable;

import java.util.Map;

/**
* A static utility class for getting empty immutable and persistent collections or creating immutable and persistent collections from mutable collections backed by the 'default' implementations.
*
* @author mtklein
* @author Yu Kobayashi
* @since 2.4.0
*/
public final class ImmutableCollections {
/**
* non-instantiable
*/
private ImmutableCollections() {
}

/**
* Creates an empty immutable deque.
*
* @return an empty immutable deque
*/
public static <E> ImmutableDeque<E> deque() {
return ImmutableDequeImpl.empty();
}

/**
* Creates an immutable deque from an iterable.
*
* @param iterable creates from
* @return the immutable deque
*/
public static <E> ImmutableDeque<E> deque(Iterable<? extends E> iterable) {
return ImmutableDequeImpl.from(iterable);
}

/**
* Creates an empty immutable list.
*
* @return an empty immutable list
*/
public static <E> ImmutableList<E> list() {
return ImmutableListImpl.empty();
}

/**
* Creates an immutable list from an iterable.
*
* @param iterable creates from
* @return the immutable list
*/
public static <E> ImmutableList<E> list(Iterable<? extends E> iterable) {
return ImmutableListImpl.from(iterable);
}

/**
* Creates an empty immutable set.
*
* @return an empty immutable set
*/
public static <E> ImmutableSet<E> set() {
return ImmutableSetImpl.empty();
}

/**
* Creates an immutable set from an iterable.
*
* @param iterable creates from
* @return the immutable set
*/
public static <E> ImmutableSet<E> set(Iterable<? extends E> iterable) {
return ImmutableSetImpl.from(iterable);
}

/**
* Creates an empty immutable list set.
*
* @return an empty immutable list set
*/
public static <E> ImmutableListSet<E> listSet() {
return ImmutableListSetImpl.empty();
}

/**
* Creates an immutable list set from an iterable.
*
* @param iterable creates from
* @return the immutable list set
*/
public static <E> ImmutableListSet<E> listSet(Iterable<? extends E> iterable) {
return ImmutableListSetImpl.from(iterable);
}

/**
* Creates an empty immutable map.
*
* @return an empty immutable map
*/
public static <K, V> ImmutableMap<K, V> map() {
return ImmutableMapImpl.empty();
}

/**
* Creates an immutable map from a mutable map.
*
* @param map creates from
* @return the immutable map
*/
public static <K, V> ImmutableMap<K, V> map(Map<? extends K, ? extends V> map) {
return ImmutableMapImpl.from(map);
}
}
Loading