001// Licensed under the Apache License, Version 2.0 (the "License");
002// you may not use this file except in compliance with the License.
003// You may obtain a copy of the License at
004//
005//     http://www.apache.org/licenses/LICENSE-2.0
006//
007// Unless required by applicable law or agreed to in writing, software
008// distributed under the License is distributed on an "AS IS" BASIS,
009// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
010// See the License for the specific language governing permissions and
011// limitations under the License.
012
013package org.apache.tapestry5.commons.util;
014
015import java.util.ArrayList;
016import java.util.Arrays;
017import java.util.Collection;
018import java.util.HashMap;
019import java.util.HashSet;
020import java.util.LinkedList;
021import java.util.List;
022import java.util.Map;
023import java.util.Set;
024import java.util.concurrent.ConcurrentHashMap;
025import java.util.concurrent.ConcurrentMap;
026import java.util.concurrent.CopyOnWriteArrayList;
027
028/**
029 * Static factory methods to ease the creation of new collection types (when using generics). Most of these method
030 * leverage the compiler's ability to match generic types by return value. Typical usage (with a static import):
031 *
032 * <pre>
033 * Map&lt;Foo, Bar&gt; map = newMap();
034 * </pre>
035 *
036 *
037 * This is a replacement for:
038 *
039 * <pre>
040 * Map&lt;Foo, Bar&gt; map = new HashMap&lt;Foo, Bar&gt;();
041 * </pre>
042 */
043public final class CollectionFactory
044{
045    /**
046     * Constructs and returns a generic {@link HashMap} instance.
047     */
048    public static <K, V> Map<K, V> newMap()
049    {
050        return new HashMap<K, V>();
051    }
052
053    /**
054     * Constructs and returns a generic {@link java.util.HashSet} instance.
055     */
056    public static <T> Set<T> newSet()
057    {
058        return new HashSet<T>();
059    }
060
061    /**
062     * Contructs a new {@link HashSet} and initializes it using the provided collection.
063     */
064    public static <T, V extends T> Set<T> newSet(Collection<V> values)
065    {
066        return new HashSet<T>(values);
067    }
068
069    public static <T, V extends T> Set<T> newSet(V... values)
070    {
071        // Was a call to newSet(), but Sun JDK can't handle that. Fucking generics.
072        return new HashSet<T>(Arrays.asList(values));
073    }
074
075    /**
076     * Constructs a new {@link java.util.HashMap} instance by copying an existing Map instance.
077     */
078    public static <K, V> Map<K, V> newMap(Map<? extends K, ? extends V> map)
079    {
080        return new HashMap<K, V>(map);
081    }
082
083    /**
084     * Constructs a new concurrent map, which is safe to access via multiple threads.
085     */
086    public static <K, V> ConcurrentMap<K, V> newConcurrentMap()
087    {
088        return new ConcurrentHashMap<K, V>();
089    }
090
091    /**
092     * Contructs and returns a new generic {@link java.util.ArrayList} instance.
093     */
094    public static <T> List<T> newList()
095    {
096        return new ArrayList<T>();
097    }
098
099    /**
100     * Creates a new, fully modifiable list from an initial set of elements.
101     */
102    public static <T, V extends T> List<T> newList(V... elements)
103    {
104        // Was call to newList(), but Sun JDK can't handle that.
105        return new ArrayList<T>(Arrays.asList(elements));
106    }
107
108    /**
109     * Useful for queues.
110     */
111    public static <T> LinkedList<T> newLinkedList()
112    {
113        return new LinkedList<T>();
114    }
115
116    /**
117     * Constructs and returns a new {@link java.util.ArrayList} as a copy of the provided collection.
118     */
119    public static <T, V extends T> List<T> newList(Collection<V> list)
120    {
121        return new ArrayList<T>(list);
122    }
123
124    /**
125     * Constructs and returns a new {@link java.util.concurrent.CopyOnWriteArrayList}.
126     */
127    public static <T> List<T> newThreadSafeList()
128    {
129        return new CopyOnWriteArrayList<T>();
130    }
131
132    public static <T> Stack<T> newStack()
133    {
134        return new Stack<T>();
135    }
136
137    public static <V> Map<String, V> newCaseInsensitiveMap()
138    {
139        return new CaseInsensitiveMap<V>();
140    }
141
142}