diff --git a/examples/showcase/src/main/java/org/springside/examples/showcase/utilities/collection/AdvancedCollectionTypeDemo.java b/examples/showcase/src/main/java/org/springside/examples/showcase/utilities/collection/AdvancedMapDemo.java similarity index 63% rename from examples/showcase/src/main/java/org/springside/examples/showcase/utilities/collection/AdvancedCollectionTypeDemo.java rename to examples/showcase/src/main/java/org/springside/examples/showcase/utilities/collection/AdvancedMapDemo.java index aa06ace3..68407db2 100644 --- a/examples/showcase/src/main/java/org/springside/examples/showcase/utilities/collection/AdvancedCollectionTypeDemo.java +++ b/examples/showcase/src/main/java/org/springside/examples/showcase/utilities/collection/AdvancedMapDemo.java @@ -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 multimap = HashMultimap.create(); + multimap.put(1, "a"); + multimap.put(2, "b"); + multimap.put(3, "c"); + multimap.put(1, "a2"); + + //取出key=1的两个值 + Collection 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 bimap = HashBiMap.create(); + bimap.put(1, "a"); + bimap.put(2, "b"); + + BiMap bimap2 = bimap.inverse(); + assertEquals(new Integer(2), bimap2.get("b")); + } /* * Guava的Table等于有兩个key的Map,可用来替代Map @@ -27,18 +66,4 @@ public class AdvancedCollectionTypeDemo { assertEquals("2a", table.get(2, "a")); } - /** - * Guava的同一个key可以有多个value的Map. - */ - @Test - public void multiMap() { - Multimap multimap = HashMultimap.create(); - multimap.put(1, "a"); - multimap.put(2, "b"); - multimap.put(3, "c"); - multimap.put(1, "a2"); - - Collection values = multimap.get(1); - assertEquals(2, values.size()); - } } diff --git a/examples/showcase/src/main/java/org/springside/examples/showcase/utilities/collection/CollectionsDemo.java b/examples/showcase/src/main/java/org/springside/examples/showcase/utilities/collection/CollectionsDemo.java new file mode 100644 index 00000000..8b2402c8 --- /dev/null +++ b/examples/showcase/src/main/java/org/springside/examples/showcase/utilities/collection/CollectionsDemo.java @@ -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 list = Lists.newArrayList(); + //创建的同时初始化数据 + List list2 = Lists.newArrayList("a", "b", "c"); + + //无需在等号右边重新定义泛型的创建HashMap + Map map = Maps.newHashMap(); + //创建Map的同时初始化值,不过这个map是不可修改的,主要用于编写测试用例。 + Map unmodifiedMap = ImmutableMap.of(1, "foo", 2, "bar"); + } + + @Test + public void operation() { + List list = Lists.newArrayList("a", "b", "c"); + List 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()); + + } +} diff --git a/examples/showcase/src/main/java/org/springside/examples/showcase/utilities/collection/SimpleWayDemo.java b/examples/showcase/src/main/java/org/springside/examples/showcase/utilities/collection/SimpleWayDemo.java deleted file mode 100644 index 7dd52505..00000000 --- a/examples/showcase/src/main/java/org/springside/examples/showcase/utilities/collection/SimpleWayDemo.java +++ /dev/null @@ -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 list = Lists.newArrayList(); - //创建的同时初始化数据 - List list2 = Lists.newArrayList("a", "b", "c"); - //无需在等号右边重新定义泛型的创建HashMap - Map map = Maps.newHashMap(); - } -} diff --git a/modules/core/src/main/java/org/springside/modules/rest/RsResponse.java b/modules/core/src/main/java/org/springside/modules/rest/RsResponse.java index fb9e3de0..39be8521 100644 --- a/modules/core/src/main/java/org/springside/modules/rest/RsResponse.java +++ b/modules/core/src/main/java/org/springside/modules/rest/RsResponse.java @@ -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(); diff --git a/modules/core/src/main/java/org/springside/modules/utils/Collections3.java b/modules/core/src/main/java/org/springside/modules/utils/Collections3.java index 737f4e1b..198cabb7 100644 --- a/modules/core/src/main/java/org/springside/modules/utils/Collections3.java +++ b/modules/core/src/main/java/org/springside/modules/utils/Collections3.java @@ -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 List subtract(final Collection a, final Collection b) { - ArrayList list = new ArrayList(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,如
mymessage
。 + * 转换Collection所有元素(通过toString())为String, 每个元素的前面加入prefix,后面加入postfix,如
mymessage
。 */ 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 getFirst(Collection collection) { + if (isEmpty(collection)) { + return null; + } + + return collection.iterator().next(); + } + + /** + * 获取Collection的最后一个元素 ,如果collection为空返回null. + */ + public static T getLast(Collection collection) { + if (isEmpty(collection)) { + return null; + } + + if (collection instanceof List) { + List list = (List) collection; + return list.get(list.size() - 1); + } + + Iterator iterator = collection.iterator(); + while (true) { + T current = iterator.next(); + if (!iterator.hasNext()) { + return current; + } + } + } + + /** + * 返回a+b的新List. + */ + public static List union(final Collection a, final Collection b) { + List result = new ArrayList(a); + result.addAll(b); + return result; + } + + /** + * 返回a-b的新List. + */ + public static List subtract(final Collection a, final Collection b) { + List list = new ArrayList(a); + for (T element : b) { + list.remove(element); + } + + return list; + } + + /** + * 返回a与b的交集的新List. + */ + public static List intersection(Collection a, Collection b) { + List list = new ArrayList(); + + for (T element : a) { + if (b.contains(element)) { + list.add(element); + } + } + return list; + } } diff --git a/modules/core/src/main/java/org/springside/modules/utils/Reflections.java b/modules/core/src/main/java/org/springside/modules/utils/Reflections.java index 5eadffc7..2732a232 100644 --- a/modules/core/src/main/java/org/springside/modules/utils/Reflections.java +++ b/modules/core/src/main/java/org/springside/modules/utils/Reflections.java @@ -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 @@ -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 Class getSuperClassGenricType(final Class clazz) { - return getSuperClassGenricType(clazz, 0); + public static Class 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. */ diff --git a/modules/core/src/test/java/org/springside/modules/utils/ReflectionsTest.java b/modules/core/src/test/java/org/springside/modules/utils/ReflectionsTest.java index 56534039..434692fd 100644 --- a/modules/core/src/test/java/org/springside/modules/utils/ReflectionsTest.java +++ b/modules/core/src/test/java/org/springside/modules/utils/ReflectionsTest.java @@ -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 diff --git a/modules/test/src/main/java/org/springside/modules/test/log/Log4jMockAppender.java b/modules/test/src/main/java/org/springside/modules/test/log/Log4jMockAppender.java index 7514652e..436796d2 100644 --- a/modules/test/src/main/java/org/springside/modules/test/log/Log4jMockAppender.java +++ b/modules/test/src/main/java/org/springside/modules/test/log/Log4jMockAppender.java @@ -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); } /**