#21 整理基础类的使用并更新文档, Collections类
This commit is contained in:
+40
-15
@@ -6,12 +6,51 @@ import java.util.Collection;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.HashBasedTable;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Table;
|
||||
|
||||
public class AdvancedCollectionTypeDemo {
|
||||
public class AdvancedMapDemo {
|
||||
|
||||
/**
|
||||
* Guava的同一个key可以有多个value的Map.
|
||||
*/
|
||||
@Test
|
||||
public void multiMap() {
|
||||
Multimap<Integer, String> multimap = HashMultimap.create();
|
||||
multimap.put(1, "a");
|
||||
multimap.put(2, "b");
|
||||
multimap.put(3, "c");
|
||||
multimap.put(1, "a2");
|
||||
|
||||
//取出key=1的两个值
|
||||
Collection<String> values = multimap.get(1);
|
||||
assertEquals(2, values.size());
|
||||
|
||||
//size是4不是3
|
||||
assertEquals(4, multimap.size());
|
||||
|
||||
//删除其中一个值
|
||||
multimap.remove(1, "a");
|
||||
assertEquals(1, multimap.get(1).size());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Guava的BiMap,可随时调转Key与Value.
|
||||
*/
|
||||
@Test
|
||||
public void BiMap() {
|
||||
BiMap<Integer, String> bimap = HashBiMap.create();
|
||||
bimap.put(1, "a");
|
||||
bimap.put(2, "b");
|
||||
|
||||
BiMap<String, Integer> bimap2 = bimap.inverse();
|
||||
assertEquals(new Integer(2), bimap2.get("b"));
|
||||
}
|
||||
|
||||
/*
|
||||
* Guava的Table等于有兩个key的Map,可用来替代Map<String,Map<String,Object>
|
||||
@@ -27,18 +66,4 @@ public class AdvancedCollectionTypeDemo {
|
||||
assertEquals("2a", table.get(2, "a"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Guava的同一个key可以有多个value的Map.
|
||||
*/
|
||||
@Test
|
||||
public void multiMap() {
|
||||
Multimap<Integer, String> multimap = HashMultimap.create();
|
||||
multimap.put(1, "a");
|
||||
multimap.put(2, "b");
|
||||
multimap.put(3, "c");
|
||||
multimap.put(1, "a2");
|
||||
|
||||
Collection<String> values = multimap.get(1);
|
||||
assertEquals(2, values.size());
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
package org.springside.examples.showcase.utilities.collection;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springside.examples.showcase.common.entity.User;
|
||||
import org.springside.modules.utils.Collections3;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
/**
|
||||
* 演示各种Collections如何简化Collection操作
|
||||
*
|
||||
* @author calvin
|
||||
*
|
||||
*/
|
||||
public class CollectionsDemo {
|
||||
|
||||
@Test
|
||||
public void init() {
|
||||
//无需在等号右边重新定义泛型的创建ArrayList
|
||||
List<String> list = Lists.newArrayList();
|
||||
//创建的同时初始化数据
|
||||
List<String> list2 = Lists.newArrayList("a", "b", "c");
|
||||
|
||||
//无需在等号右边重新定义泛型的创建HashMap
|
||||
Map<String, ? extends User> map = Maps.newHashMap();
|
||||
//创建Map的同时初始化值,不过这个map是不可修改的,主要用于编写测试用例。
|
||||
Map<Integer, String> unmodifiedMap = ImmutableMap.of(1, "foo", 2, "bar");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void operation() {
|
||||
List<String> list = Lists.newArrayList("a", "b", "c");
|
||||
List<String> list2 = Lists.newArrayList("a", "b");
|
||||
|
||||
//nullsafe的判断是否为空
|
||||
assertFalse(Collections3.isEmpty(list));
|
||||
|
||||
//获取最后一个
|
||||
assertEquals("c", Collections3.getLast(list));
|
||||
|
||||
//list+list2的新List
|
||||
List result = Collections3.union(list, list2);
|
||||
assertEquals("[a, b, c, a, b]", result.toString());
|
||||
|
||||
//list-list2的新List
|
||||
result = Collections3.subtract(list, list2);
|
||||
assertEquals("[c]", result.toString());
|
||||
|
||||
//list与list2的交集的新List
|
||||
result = Collections3.intersection(list, list2);
|
||||
assertEquals("[a, b]", result.toString());
|
||||
|
||||
}
|
||||
}
|
||||
-23
@@ -1,23 +0,0 @@
|
||||
package org.springside.examples.showcase.utilities.collection;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springside.examples.showcase.common.entity.User;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
public class SimpleWayDemo {
|
||||
|
||||
@Test
|
||||
public void simple() {
|
||||
//无需在等号右边重新定义泛型的创建ArrayList
|
||||
List<String> list = Lists.newArrayList();
|
||||
//创建的同时初始化数据
|
||||
List<String> list2 = Lists.newArrayList("a", "b", "c");
|
||||
//无需在等号右边重新定义泛型的创建HashMap
|
||||
Map<String, ? extends User> map = Maps.newHashMap();
|
||||
}
|
||||
}
|
||||
@@ -60,14 +60,14 @@ public class RsResponse {
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建类型为"application/plain"的Response。
|
||||
* 创建类型为"application/json"的Response。
|
||||
*/
|
||||
public static Response buildJsonResponse(Status status, Object content) {
|
||||
return buildJsonResponse(status.getStatusCode(), content);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建类型为"application/plain"的Response。
|
||||
* 创建类型为"application/json"的Response。
|
||||
*/
|
||||
public static Response buildJsonResponse(int status, Object content) {
|
||||
return Response.status(status).entity(content).type(MediaType.APPLICATION_JSON).build();
|
||||
|
||||
@@ -8,6 +8,7 @@ package org.springside.modules.utils;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -23,18 +24,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||
public class Collections3 {
|
||||
|
||||
/**
|
||||
* 返回a-b的集合.
|
||||
*/
|
||||
public static <T> List<T> subtract(final Collection<T> a, final Collection<T> b) {
|
||||
ArrayList<T> list = new ArrayList<T>(a);
|
||||
for (Object element : b) {
|
||||
list.remove(element);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 提取集合中的对象的属性(通过Getter函数), 组合成Map.
|
||||
* 提取集合中的对象的两个属性(通过Getter函数), 组合成Map.
|
||||
*
|
||||
* @param collection 来源集合.
|
||||
* @param keyPropertyName 要提取为Map中的Key值的属性名.
|
||||
@@ -57,7 +47,7 @@ public class Collections3 {
|
||||
}
|
||||
|
||||
/**
|
||||
* 提取集合中的对象的属性(通过Getter函数), 组合成List.
|
||||
* 提取集合中的对象的一个属性(通过Getter函数), 组合成List.
|
||||
*
|
||||
* @param collection 来源集合.
|
||||
* @param propertyName 要提取的属性名.
|
||||
@@ -77,7 +67,7 @@ public class Collections3 {
|
||||
}
|
||||
|
||||
/**
|
||||
* 提取集合中的对象的属性(通过Getter函数), 组合成由分割符分隔的字符串.
|
||||
* 提取集合中的对象的一个属性(通过Getter函数), 组合成由分割符分隔的字符串.
|
||||
*
|
||||
* @param collection 来源集合.
|
||||
* @param propertyName 要提取的属性名.
|
||||
@@ -89,14 +79,14 @@ public class Collections3 {
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换Collection为String, 中间以 separator分隔。
|
||||
* 转换Collection所有元素(通过toString())为String, 中间以 separator分隔。
|
||||
*/
|
||||
public static String convertToString(final Collection collection, final String separator) {
|
||||
return StringUtils.join(collection, separator);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换Collection为String, 每个元素的前面加入prefix,后面加入postfix,如<div>mymessage</div>。
|
||||
* 转换Collection所有元素(通过toString())为String, 每个元素的前面加入prefix,后面加入postfix,如<div>mymessage</div>。
|
||||
*/
|
||||
public static String convertToString(final Collection collection, final String prefix, final String postfix) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
@@ -105,4 +95,79 @@ public class Collections3 {
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否为空.
|
||||
*/
|
||||
public static boolean isEmpty(Collection collection) {
|
||||
return (collection == null || collection.isEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
* 取得Collection的第一个元素,如果collection为空返回null.
|
||||
*/
|
||||
public static <T> T getFirst(Collection<T> collection) {
|
||||
if (isEmpty(collection)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return collection.iterator().next();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Collection的最后一个元素 ,如果collection为空返回null.
|
||||
*/
|
||||
public static <T> T getLast(Collection<T> collection) {
|
||||
if (isEmpty(collection)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (collection instanceof List) {
|
||||
List<T> list = (List<T>) collection;
|
||||
return list.get(list.size() - 1);
|
||||
}
|
||||
|
||||
Iterator<T> iterator = collection.iterator();
|
||||
while (true) {
|
||||
T current = iterator.next();
|
||||
if (!iterator.hasNext()) {
|
||||
return current;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回a+b的新List.
|
||||
*/
|
||||
public static <T> List<T> union(final Collection<T> a, final Collection<T> b) {
|
||||
List<T> result = new ArrayList<T>(a);
|
||||
result.addAll(b);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回a-b的新List.
|
||||
*/
|
||||
public static <T> List<T> subtract(final Collection<T> a, final Collection<T> b) {
|
||||
List<T> list = new ArrayList<T>(a);
|
||||
for (T element : b) {
|
||||
list.remove(element);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回a与b的交集的新List.
|
||||
*/
|
||||
public static <T> List<T> intersection(Collection<T> a, Collection<T> b) {
|
||||
List<T> list = new ArrayList<T>();
|
||||
|
||||
for (T element : a) {
|
||||
if (b.contains(element)) {
|
||||
list.add(element);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,9 +25,6 @@ import org.slf4j.LoggerFactory;
|
||||
* @author calvin
|
||||
*/
|
||||
public class Reflections {
|
||||
|
||||
private static final String CGLIB_CLASS_SEPARATOR = "$$";
|
||||
|
||||
private static final String SETTER_PREFIX = "set";
|
||||
|
||||
private static final String GETTER_PREFIX = "get";
|
||||
@@ -212,7 +209,7 @@ public class Reflections {
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过反射, 获得Class定义中声明的父类的泛型参数的类型.
|
||||
* 通过反射, 获得Class定义中声明的泛型参数的类型, 注意泛型必须定义在父类处
|
||||
* 如无法找到, 返回Object.class.
|
||||
* eg.
|
||||
* public UserDao extends HibernateDao<User>
|
||||
@@ -220,8 +217,8 @@ public class Reflections {
|
||||
* @param clazz The class to introspect
|
||||
* @return the first generic declaration, or Object.class if cannot be determined
|
||||
*/
|
||||
public static <T> Class<T> getSuperClassGenricType(final Class clazz) {
|
||||
return getSuperClassGenricType(clazz, 0);
|
||||
public static <T> Class<T> getClassGenricType(final Class clazz) {
|
||||
return getClassGenricType(clazz, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -234,7 +231,7 @@ public class Reflections {
|
||||
* @param index the Index of the generic ddeclaration,start from 0.
|
||||
* @return the index generic declaration, or Object.class if cannot be determined
|
||||
*/
|
||||
public static Class getSuperClassGenricType(final Class clazz, final int index) {
|
||||
public static Class getClassGenricType(final Class clazz, final int index) {
|
||||
|
||||
Type genType = clazz.getGenericSuperclass();
|
||||
|
||||
@@ -258,19 +255,6 @@ public class Reflections {
|
||||
return (Class) params[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* 对于被cglib AOP过的对象, 取得真实的Class类型.
|
||||
*/
|
||||
public static Class<?> getUnproxyClass(Class<?> clazz) {
|
||||
if (clazz != null && clazz.getName().contains(CGLIB_CLASS_SEPARATOR)) {
|
||||
Class<?> superClass = clazz.getSuperclass();
|
||||
if (superClass != null && !Object.class.equals(superClass)) {
|
||||
return superClass;
|
||||
}
|
||||
}
|
||||
return clazz;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将反射时的checked exception转换为unchecked exception.
|
||||
*/
|
||||
|
||||
@@ -92,14 +92,14 @@ public class ReflectionsTest {
|
||||
@Test
|
||||
public void getSuperClassGenricType() {
|
||||
//获取第1,2个泛型类型
|
||||
assertEquals(String.class, Reflections.getSuperClassGenricType(TestBean.class));
|
||||
assertEquals(Long.class, Reflections.getSuperClassGenricType(TestBean.class, 1));
|
||||
assertEquals(String.class, Reflections.getClassGenricType(TestBean.class));
|
||||
assertEquals(Long.class, Reflections.getClassGenricType(TestBean.class, 1));
|
||||
|
||||
//定义父类时无泛型定义
|
||||
assertEquals(Object.class, Reflections.getSuperClassGenricType(TestBean2.class));
|
||||
assertEquals(Object.class, Reflections.getClassGenricType(TestBean2.class));
|
||||
|
||||
//无父类定义
|
||||
assertEquals(Object.class, Reflections.getSuperClassGenricType(TestBean3.class));
|
||||
assertEquals(Object.class, Reflections.getClassGenricType(TestBean3.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -12,6 +12,7 @@ import org.apache.log4j.Logger;
|
||||
import org.apache.log4j.PatternLayout;
|
||||
import org.apache.log4j.spi.LoggingEvent;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
/**
|
||||
@@ -52,7 +53,7 @@ public class Log4jMockAppender extends AppenderSkeleton {
|
||||
if (logs.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return logs.get(logs.size() - 1);
|
||||
return Iterables.getLast(logs);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user