package my.tools; |
002 | |
003 | import java.util.Set; |
004 | import java.util.Map; |
005 | import java.util.List; |
006 | import java.util.Queue; |
007 | import java.util.HashSet; |
008 | import java.util.HashMap; |
009 | import java.util.TreeMap; |
010 | import java.util.TreeSet; |
011 | import java.util.ArrayList; |
012 | import java.util.Collection; |
013 | import java.util.LinkedList; |
014 | import java.util.LinkedHashMap; |
015 | import java.util.concurrent.ConcurrentHashMap; |
016 | import java.util.concurrent.ConcurrentMap; |
017 | |
018 | /** |
019 | * 包含获得各种集合对象的常用方法的泛型工具类。 |
020 | * <p> |
021 | * 如果要获得一个 {@code Map<String, String>} 的对象,可以通过下面的方式实现: |
022 | * {@literal Map<String, String> map = GenericUtils.getMap();}。但是不能直接作为参数使用,例如有这样一个方法: |
023 | * {@literal setInfo(Map<String, String>)},不能直接这样调用:<s> |
024 | * <code>setInfo(GenericUtils.getMap())</code></s> |
025 | * </p> |
026 | * |
027 | * @author Fuchun |
028 | * @version $Id: GenericUtils.java 4754 2011-03-26 19:50 fuchun $ |
029 | */ |
030 | public class GenericUtils { |
031 | |
032 | /** |
033 | * 用该方法来代替 {@code new HashMap<K, V>()} 方式获得新的 {@code java.util.Map} 的实例对象。 |
034 | * |
035 | * @param <K> {@code Map} 中的键对象。 |
036 | * @param <V> {@code Map} 中的值对象。 |
037 | * @return 返回 {@code java.util.Map<K, V>} 关于 {@code java.util.HashMap<K, V>} 实现的新实例。 |
038 | */ |
039 | public static <K, V> Map<K, V> getMap() { |
040 | return new HashMap<K, V>(); |
041 | } |
042 | |
043 | /** |
044 | * 用该方法来代替 {@code new HashMap<K, V>(int)} 方式获得新的 {@code java.util.Map} 的实例对象。 |
045 | * |
046 | * @param <K> {@code Map} 中的键对象。 |
047 | * @param <V> {@code Map} 中的值对象。 |
048 | * @param initialCapacity 初始容量。 |
049 | * @return 返回 {@code java.util.Map<K, V>} 关于 {@code java.util.HashMap<K, V>} 实现的新实例。 |
050 | */ |
051 | public static <K, V> Map<K, V> getMap( int initialCapacity) { |
052 | return new HashMap<K, V>(initialCapacity); |
053 | } |
054 | |
055 | /** |
056 | * 用该方法来代替 {@code new ConcurrentHashMap<K, V>()} 方式获得新的 {@code java.util.Map} 的实例对象。 |
057 | * |
058 | * @param <K> {@code Map} 中的键对象。 |
059 | * @param <V> {@code Map} 中的值对象。 |
060 | * @return 返回 {@code java.util.Map<K, V>} 关于 |
061 | * {@code java.util.concurrent.ConcurrentHashMap<K, V>} 实现的新实例。 |
062 | */ |
063 | public static <K, V> Map<K, V> getConcurrentMap() { |
064 | return new ConcurrentHashMap<K, V>(); |
065 | } |
066 | |
067 | /** |
068 | * 用该方法来代替 {@code new ConcurrentHashMap<K, V>(int)} 方式获得新的 {@code java.util.Map} |
069 | * 的实例对象。 |
070 | * |
071 | * @param <K> {@code Map} 中的键对象。 |
072 | * @param <V> {@code Map} 中的值对象。 |
073 | * @param initialCapacity 初始容量。 |
074 | * @return 返回 {@code java.util.Map<K, V>} 关于 |
075 | * {@code java.util.concurrent.ConcurrentHashMap<K, V>} 实现的新实例。 |
076 | */ |
077 | public static <K, V> Map<K, V> getConcurrentMap( int initialCapacity) { |
078 | return new ConcurrentHashMap<K, V>(initialCapacity); |
079 | } |
080 | |
081 | /** |
082 | * 用该方法来代替 {@code new LinkedHashMap<K, V>()} 方式获得新的 {@code java.util.Map} 的实例对象。 |
083 | * |
084 | * @param <K> {@code Map} 中的键对象。 |
085 | * @param <V> {@code Map} 中的值对象。 |
086 | * @return 返回 {@code java.util.Map<K, V>} 关于 {@code java.util.LinkedHashMap<K, V>} |
087 | * 实现的新实例。 |
088 | */ |
089 | public static <K, V> Map<K, V> getLinkedMap() { |
090 | return new LinkedHashMap<K, V>(); |
091 | } |
092 | |
093 | /** |
094 | * 用该方法来代替 {@code new LinkedHashMap<K, V>(int)} 方式获得新的 {@code java.util.Map} 的实例对象。 |
095 | * |
096 | * @param <K> {@code Map} 中的键对象。 |
097 | * @param <V> {@code Map} 中的值对象。 |
098 | * @param initialCapacity 初始容量。 |
099 | * @return 返回 {@code java.util.Map<K, V>} 关于 {@code java.util.LinkedHashMap<K, V>} |
100 | * 实现的新实例。 |
101 | */ |
102 | public static <K, V> Map<K, V> getLinkedMap( int initialCapacity) { |
103 | return new LinkedHashMap<K, V>(initialCapacity); |
104 | } |
105 | |
106 | /** |
107 | * 用该方法来代替 {@code new TreeMap<K, V>()} 方式获得新的 {@code java.util.Map} 的实例对象。 |
108 | * |
109 | * @param <K> {@code Map} 中的键对象。 |
110 | * @param <V> {@code Map} 中的值对象。 |
111 | * @return 返回 {@code java.util.Map<K, V>} 关于 {@code java.util.TreeMap<K, V>} 实现的新实例。 |
112 | */ |
113 | public static <K, V> Map<K, V> getTreeMap() { |
114 | return new TreeMap<K, V>(); |
115 | } |
116 | |
117 | /** |
118 | * 用该方法来代替 {@code new ConcurrentHashMap<K, V>()} 方式获得新的 |
119 | * {@code java.util.concurrent.ConcurrentHashMap} 的实例对象。 |
120 | * |
121 | * @param <K> {@code Map} 中的键对象。 |
122 | * @param <V> {@code Map} 中的值对象。 |
123 | * @return 返回 {@code java.util.concurrent.ConcurrentMap<K, V>} 关于 |
124 | * {@code java.util.concurrent.ConcurrentHashMap<K, V>} 实现的新实例。 |
125 | */ |
126 | public static <K, V> ConcurrentMap<K, V> getConcurrentHashMap() { |
127 | return new ConcurrentHashMap<K, V>(); |
128 | } |
129 | |
130 | /** |
131 | * 用该方法来代替 {@code new ConcurrentHashMap<K, V>(int)} 方式获得新的 |
132 | * {@code java.util.concurrent.ConcurrentHashMap} 的实例对象。 |
133 | * |
134 | * @param <K> {@code Map} 中的键对象。 |
135 | * @param <V> {@code Map} 中的值对象。 |
136 | * @param initialCapacity 初始容量。 |
137 | * @return 返回 {@code java.util.concurrent.ConcurrentMap<K, V>} 关于 |
138 | * {@code java.util.concurrent.ConcurrentHashMap<K, V>} 实现的新实例。 |
139 | */ |
140 | public static <K, V> ConcurrentMap<K, V> getConcurrentHashMap( int initialCapacity) { |
141 | return new ConcurrentHashMap<K, V>(initialCapacity); |
142 | } |
143 | |
144 | /** |
145 | * 用该方法来代替 {@code new ArrayList<T>()} 方式获得新的 {@code java.util.List} 的实例对象。 |
146 | * |
147 | * @param <T> {@code List<T>} 中保存的对象。 |
148 | * @return 返回 {@code java.util.List<T>} 关于 {@code java.util.ArrayList<T>} 实现的新实例。 |
149 | */ |
150 | public static <T> List<T> getList() { |
151 | return new ArrayList<T>(); |
152 | } |
153 | |
154 | /** |
155 | * 用该方法来代替 {@code new ArrayList<T>(int)} 方式获得新的 {@code java.util.List} 的实例对象。 |
156 | * |
157 | * @param <T> {@code List<T>} 中保存的对象。 |
158 | * @param initialCapacity 列表的初始容量。 |
159 | * @return 返回 {@code java.util.List<T>} 关于 {@code java.util.ArrayList<T>} 实现的新实例。 |
160 | */ |
161 | public static <T> List<T> getList( int initialCapacity) { |
162 | return new ArrayList<T>(initialCapacity); |
163 | } |
164 | |
165 | /** |
166 | * 用该方法来代替 {@code new ArrayList<T>()} 方式获得新的 {@code java.util.List} 的实例对象。 |
167 | * |
168 | * @param <T> {@code List<T>} 中保存的对象。 |
169 | * @param c 其中的元素将存放在新的 {@code list} 中的 {@code collection}。 |
170 | * @return 返回 {@code java.util.List<T>} 关于 {@code java.util.ArrayList<T>} 实现的新实例。 |
171 | */ |
172 | public static <T> List<T> getList(Collection<? extends T> c) { |
173 | if (ObjectUtils.isNotEmpty(c)) |
174 | return new ArrayList<T>(c); |
175 | return new ArrayList<T>(); |
176 | } |
177 | |
178 | /** |
179 | * 用该方法来代替 {@code new LinkedList<T>()} 方式获得新的 {@code java.util.List} 的实例对象。 |
180 | * |
181 | * @param <T> {@code List<T>} 中保存的对象。 |
182 | * @return 返回 {@code java.util.List<T>} 关于 {@code java.util.LinkedList<T>} 实现的新实例。 |
183 | */ |
184 | public static <T> List<T> getLinkedList() { |
185 | return new LinkedList<T>(); |
186 | } |
187 | |
188 | /** |
189 | * 用该方法来代替 {@code new HashSet<T>()} 方式获得新的 {@code java.util.Set} 的实例对象。 |
190 | * |
191 | * @param <T> {@code Set<T>} 中保存的对象。 |
192 | * @return 返回 {@code java.util.Set<T>} 关于 {@code java.util.HashSet<T>} 实现的新实例。 |
193 | */ |
194 | public static <T> Set<T> getHashSet() { |
195 | return new HashSet<T>(); |
196 | } |
197 | |
198 | /** |
199 | * 用该方法来代替 {@code new HashSet<T>(int)} 方式获得新的 {@code java.util.Set} 的实例对象。 |
200 | * |
201 | * @param <T> {@code Set<T>} 中保存的对象。 |
202 | * @param initialCapacity 列表的初始容量。 |
203 | * @return 返回 {@code java.util.Set<T>} 关于 {@code java.util.HashSet<T>} 实现的新实例。 |
204 | */ |
205 | public static <T> Set<T> getHashSet( int initialCapacity) { |
206 | return new HashSet<T>(initialCapacity); |
207 | } |
208 | |
209 | /** |
210 | * 用该方法来代替 <code>new HashSet<T>(Collection<? extends T> c)</code> 方式获得新的 |
211 | * {@code java.util.Set} 的实例对象。 |
212 | * |
213 | * @param <T> {@code Set} 中保存的对象。 |
214 | * @param c 其中的元素将存放在新的 {@code set} 中的 {@code collection}。 |
215 | * @return 返回 {@code java.util.Set<T>} 关于 {@code java.util.HashSet<T>} 实现的新实例。 |
216 | */ |
217 | public static <T> Set<T> getHashSet(Collection<? extends T> c) { |
218 | if (ObjectUtils.isEmpty(c)) |
219 | return new HashSet<T>(); |
220 | return new HashSet<T>(c); |
221 | } |
222 | |
223 | /** |
224 | * 用该方法来代替 {@code new TreeSet<T>()} 方式获得新的 {@code java.util.Set} 的实例对象。 |
225 | * |
226 | * @param <T> {@code Set<T>} 中保存的对象。 |
227 | * @return 返回 {@code java.util.Set<T>} 关于 {@code java.util.TreeSet<T>} 实现的新实例。 |
228 | */ |
229 | public static <T> Set<T> getTreeSet() { |
230 | return new TreeSet<T>(); |
231 | } |
232 | |
233 | /** |
234 | * 用该方法来代替 <code>new TreeSet<T>(Collection<? extends T> c)</code> 方式获得新的 |
235 | * {@code java.util.Set} 的实例对象。 |
236 | * |
237 | * @param <T> {@code Set} 中保存的对象。 |
238 | * @param c 其中的元素将存放在新的 {@code set} 中的 {@code collection}。 |
239 | * @return 返回 {@code java.util.Set<T>} 关于 {@code java.util.TreeSet<T>} 实现的新实例。 |
240 | */ |
241 | public static <T> Set<T> getTreeSet(Collection<? extends T> c) { |
242 | if (ObjectUtils.isEmpty(c)) |
243 | return new TreeSet<T>(); |
244 | return new TreeSet<T>(c); |
245 | } |
246 | |
247 | /** |
248 | * 用该方法来代替 {@code new LinkedList<E>()} 方式获得新的 {@code java.util.Queue} 的实例对象。 |
249 | * |
250 | * @param <E> {@code Queue<E>} 中保存的对象。 |
251 | * @return 返回 {@code java.util.Queue<E>} 关于 {@code java.util.LinkedList<E>} 实现的新实例。 |
252 | */ |
253 | public static <E> Queue<E> getQueue() { |
254 | return new LinkedList<E>(); |
255 | } |
256 | |
257 | /** |
258 | * 合并两个有相同元素类型的 {@code java.util.Set}。 |
259 | * <ul> |
260 | * <li>{@code setA == null && setB == null} --> 返回 {@link #getHashSet()}。</li> |
261 | * <li>{@code setA != null && setB == null} --> 返回 {@code setA}。</li> |
262 | * <li>{@code setA == null && setB != null} --> 返回 {@code setB}。</li> |
263 | * <li>{@code setA != null && setB != null} --> 返回 {@code setA} 和 {@code setB} 的并集。 |
264 | * </li> |
265 | * </ul> |
266 | * |
267 | * @param <T> {@code Set} 中保存的对象。 |
268 | * @param setA 第一个 {@code Set}。 |
269 | * @param setB 第二个 {@code Set}。 |
270 | * @return 返回 {@code setA} 和 {@code setB} 的并集。 |
271 | */ |
272 | public static <T> Set<T> unionHashSet(Set<T> setA, Set<T> setB) { |
273 | boolean isEmptySetA = ObjectUtils.isEmpty(setA); |
274 | boolean isEmptySetB = ObjectUtils.isEmpty(setB); |
275 | if (isEmptySetA && isEmptySetB) |
276 | return getHashSet(); |
277 | if (isEmptySetA && !isEmptySetB) |
278 | return setB; |
279 | if (!isEmptySetA && isEmptySetB) |
280 | return setA; |
281 | Set<T> result = getHashSet(setA); |
282 | result.addAll(setB); |
283 | return result; |
284 | } |
285 | |
286 | /** |
287 | * 取两个有相同元素类型的 {@code java.util.Set} 的交集,即公共部份的新的 {@code java.util.Set}。 |
288 | * <ul> |
289 | * <li>{@code setA == null && setB == null} --> 返回 {@code null}。</li> |
290 | * <li>{@code setA != null && setB == null} --> 返回 {@code null}。</li> |
291 | * <li>{@code setA == null && setB != null} --> 返回 {@code null}。</li> |
292 | * <li>{@code setA != null && setB != null} --> 返回 {@code setA} 和 {@code setB} 的交集。 |
293 | * </li> |
294 | * </ul> |
295 | * |
296 | * @param <T> {@code Set} 中保存的对象。 |
297 | * @param setA 第一个 {@code Set}。 |
298 | * @param setB 第二个 {@code Set}。 |
299 | * @return 返回 {@code setA} 和 {@code setB} 的交集。 |
300 | */ |
301 | public static <T> Set<T> intersectHashSet(Set<T> setA, Set<T> setB) { |
302 | if (ObjectUtils.isEmpty(setA) || ObjectUtils.isEmpty(setB)) |
303 | return null ; |
304 | Set<T> result = getHashSet(setA); |
305 | result.retainAll(setB); |
306 | return result; |
307 | } |
308 | |
309 | /** |
310 | * 移除 {@code setA} 中那些包含在 {@code setB} 中的元素。<br /> |
311 | * 此方法不会修改 {@code setA},只是复制一份作相应操作,返回的是全新的 {@code Set} 对象。 |
312 | * <ul> |
313 | * <li>{@code setA == null} --> 返回 {@code null}。</li> |
314 | * <li>{@code setB == null} --> 返回 {@code setA}。</li> |
315 | * <li>{@code setA != null && setB != null} --> 返回 {@code setA} 和 {@code setB} |
316 | * 的不对称差集。</li> |
317 | * </ul> |
318 | * |
319 | * @param <T> {@code Set} 中保存的对象。 |
320 | * @param setA 第一个 {@code Set}。 |
321 | * @param setB 第二个 {@code Set}。 |
322 | * @return 返回 {@code setA} 和 {@code setB} 的不对称差集。 |
323 | */ |
324 | public static <T> Set<T> differenceHashSet(Set<T> setA, Set<T> setB) { |
325 | if (ObjectUtils.isEmpty(setA)) |
326 | return null ; |
327 | if (ObjectUtils.isEmpty(setB)) |
328 | return setA; |
329 | Set<T> result = getHashSet(setA); |
330 | result.removeAll(setB); |
331 | return result; |
332 | } |
333 | |
334 | /** |
335 | * 取两个有相同元素类型的 {@code java.util.Set} 的补集。 |
336 | * |
337 | * @param <T> {@code Set} 中保存的对象。 |
338 | * @param setA 第一个 {@code Set}。 |
339 | * @param setB 第二个 {@code Set}。 |
340 | * @return 返回 {@code setA} 和 {@code setB} 的补集。 |
341 | */ |
342 | public static <T> Set<T> complementHashSet(Set<T> setA, Set<T> setB) { |
343 | return differenceHashSet(unionHashSet(setA, setB), intersectHashSet(setA, setB)); |
344 | } |
345 |