Last active
September 23, 2016 12:24
-
-
Save lzxz1234/d07b786414b93ea6734d945bdc1e7880 to your computer and use it in GitHub Desktop.
Lang
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.bj58.zb.service.core.utils; | |
import static org.apache.commons.collections.ComparatorUtils.naturalComparator; | |
import static org.apache.commons.collections.ComparatorUtils.nullHighComparator; | |
import static org.apache.commons.collections.ComparatorUtils.reversedComparator; | |
import java.lang.annotation.ElementType; | |
import java.lang.annotation.Inherited; | |
import java.lang.annotation.Retention; | |
import java.lang.annotation.RetentionPolicy; | |
import java.lang.annotation.Target; | |
import java.lang.reflect.Constructor; | |
import java.lang.reflect.Method; | |
import java.lang.reflect.Modifier; | |
import java.util.ArrayList; | |
import java.util.Collection; | |
import java.util.Collections; | |
import java.util.Comparator; | |
import java.util.HashMap; | |
import java.util.List; | |
import java.util.Map; | |
import java.util.concurrent.Callable; | |
import java.util.concurrent.ExecutorService; | |
import java.util.concurrent.Executors; | |
import java.util.concurrent.Future; | |
import java.util.regex.Pattern; | |
import org.apache.commons.collections.CollectionUtils; | |
import org.apache.log4j.Logger; | |
import net.sf.cglib.proxy.Enhancer; | |
import net.sf.cglib.proxy.MethodInterceptor; | |
import net.sf.cglib.proxy.MethodProxy; | |
import reactor.util.StringUtils; | |
@SuppressWarnings("unchecked") | |
public class Lang { | |
private static Logger log = Logger.getLogger(Lang.class); | |
private static ExecutorService exec = Executors.newFixedThreadPool(20); | |
/** | |
* 将列表按指定属性映射成 map | |
* @param list ArrayList<Bid> | |
* @param mapProp id | |
* @return Map<id, Bid> | |
* @throws Exception | |
*/ | |
public static final <K, V> Map<K, V> map(Collection<V> list, String mapProp) throws Exception { | |
if(list == null) return null; | |
if(list.size() == 0) return new HashMap<K, V>(0); | |
Class<?> target = list.iterator().next().getClass(); | |
Method getMethod = MethodUtils.getGetter(target, mapProp); | |
if(getMethod == null) | |
throw new RuntimeException("类[" + target.getSimpleName() + "]缺少[" + mapProp + "]属性"); | |
Map<K, V> map = new HashMap<K, V>(); | |
for(V v : list) | |
map.put((K) getMethod.invoke(v), v); | |
return map; | |
} | |
/** | |
* @param list ArrayList<Bid> | |
* @param collectProp id | |
* @return List<bidId> | |
* @throws Exception | |
*/ | |
public static final <T> List<T> collect(List<?> list, String collectProp) throws Exception { | |
if(list == null) return null; | |
if(list.size() == 0) return new ArrayList<T>(0); | |
Class<?> target = list.get(0).getClass(); | |
Method getMethod = MethodUtils.getGetter(target, collectProp); | |
if(getMethod == null) | |
throw new RuntimeException("类[" + target.getSimpleName() + "]缺少[" + collectProp + "]属性"); | |
List<T> result = new ArrayList<T>(list.size()); | |
for(Object obj : list) | |
result.add((T) getMethod.invoke(obj)); | |
return result; | |
} | |
public static final <T> T getRegex(Map<String, T> map, String regex) { | |
if(StringUtils.isEmpty(regex) || map == null) return null; | |
Pattern pattern = Pattern.compile(regex); | |
for(Map.Entry<String, T> entry : map.entrySet()) | |
if(pattern.matcher(entry.getKey()).matches()) | |
return entry.getValue(); | |
return null; | |
} | |
/** | |
* 匹配 src 对象上的 get 方法,循环调用 dest 上对应的 set 方法 | |
* @param src | |
* @param dest | |
* @throws Exception | |
*/ | |
public static final void copy(Object src, Object dest) throws Exception { | |
if(src == null || dest == null) return; | |
List<Method> list = MethodUtils.getMethodRegex(src.getClass(), "get.+"); | |
Class<?> destClass = dest.getClass(); | |
for(Method method : list) { | |
String setName = method.getName().replaceFirst("get", "set"); | |
Method setMethod = MethodUtils.getMethod(destClass, setName, method.getReturnType()); | |
if(setMethod != null) | |
setMethod.invoke(dest, method.invoke(src)); | |
} | |
} | |
/** | |
* 按指定字段去重 <br> | |
* {id=1, name='Red'} 和 {id=2, name='Blue'} 按 name 字段去重后随机获得其中一个 | |
* @param list | |
* @param field | |
* @return | |
* @throws Exception | |
*/ | |
public static final <T> List<T> distinct(List<T> list, String field) throws Exception { | |
if(CollectionUtils.isEmpty(list)) return list; | |
Map<String, T> map = Lang.map(list, field); | |
return new ArrayList<T>(map.values()); | |
} | |
/** | |
* 按列表中的指定字段排序 | |
* @param list | |
* @param field | |
* @throws Exception | |
*/ | |
public static final <T> void sortAsc(List<T> list, String field) throws Exception { | |
if(CollectionUtils.isEmpty(list)) return; | |
final Method getter = MethodUtils.getGetter(list.get(0).getClass(), field); | |
Collections.sort(list, nullHighComparator(new Comparator<T>() { | |
@Override | |
public int compare(T o1, T o2) { | |
try { | |
Object field1 = getter.invoke(o1); | |
Object field2 = getter.invoke(o2); | |
return nullHighComparator(naturalComparator()).compare(field1, field2); | |
} catch (Exception e) { | |
throw new RuntimeException("排序失败", e); | |
} | |
} | |
})); | |
} | |
public static final <T> void sortDesc(List<T> list, String field) throws Exception { | |
if(CollectionUtils.isEmpty(list)) return; | |
final Method getter = MethodUtils.getGetter(list.get(0).getClass(), field); | |
Collections.sort(list, nullHighComparator(new Comparator<T>() { | |
@Override | |
public int compare(T o1, T o2) { | |
try { | |
Object field1 = getter.invoke(o1); | |
Object field2 = getter.invoke(o2); | |
return nullHighComparator(reversedComparator(naturalComparator())).compare(field1, field2); | |
} catch (Exception e) { | |
throw new RuntimeException("排序失败", e); | |
} | |
} | |
})); | |
} | |
/** | |
* 对列表中单独属性求和 | |
* @param list | |
* @param field | |
* @return | |
* @throws Exception | |
*/ | |
public static final <T> double sum(List<T> list, String field) throws Exception { | |
if(CollectionUtils.isEmpty(list)) return 0; | |
final Method getter = MethodUtils.getGetter(list.get(0).getClass(), field); | |
if(getter == null) | |
throw new RuntimeException("Class: " + list.get(0).getClass().getName() + " 没有 " + field + " 对应的 get 方法"); | |
double result = 0; | |
for(T each : list) { | |
Object object = getter.invoke(each); | |
if(object == null) continue; | |
if (object instanceof Number) { | |
result += ((Number) object).doubleValue(); | |
} else { | |
throw new RuntimeException("非 Number 类型无法求和"); | |
} | |
} | |
return result; | |
} | |
/** | |
* 自动异步处理工具,对传入的对象生成代理,所有调用该对象中被 <code>Concurrent</code> | |
* 注解的方法都会快速返回结果,只要不调用结果的任何方法就不会阻塞 <br> | |
* 另当被代理方法的返回类型为 Final 或者没有无参构造方法时会顺序执行 | |
* @param rawObj | |
* @return | |
*/ | |
public static <T> T autoConcurrent(final T rawObj) { | |
if(rawObj == null || !couldEnhancer(rawObj.getClass())) { | |
log.warn("类 " + (rawObj == null ? "null" : rawObj.getClass().getName()) + " 为 final 或没有无参构造函数无法生成代理"); | |
return rawObj; | |
} | |
Enhancer enhancer = new Enhancer(); | |
enhancer.setSuperclass(rawObj.getClass()); | |
enhancer.setCallback(new MethodInterceptor() { | |
@Override | |
public Object intercept(Object obj, final Method method, Object[] args, | |
MethodProxy proxy) throws Throwable { | |
if(method.getAnnotation(Concurrent.class) != null) { | |
Class<?> returnType = method.getReturnType(); | |
if(couldEnhancer(returnType)) { | |
final Future<Object> future = exec.submit(new Callable<Object>() { | |
@Override | |
public Object call() throws Exception { | |
return method.invoke(rawObj); | |
} | |
}); | |
Enhancer enhancer = new Enhancer(); | |
enhancer.setSuperclass(returnType); | |
enhancer.setCallback(new MethodInterceptor() { | |
@Override | |
public Object intercept(Object obj, Method method, Object[] args, | |
MethodProxy proxy) throws Throwable { | |
return method.invoke(future.get(), args); | |
} | |
}); | |
return enhancer.create(); | |
} else | |
log.warn("类 " + obj.getClass() + " 的方法 " + method.getName() + "返回类型为 final 或者没有无参构造函数不能生成代理"); | |
} | |
return proxy.invokeSuper(obj, args); | |
} | |
}); | |
enhancer.setClassLoader(rawObj.getClass().getClassLoader()); | |
return (T) enhancer.create(); | |
} | |
private static boolean couldEnhancer(Class<?> clazz) { | |
if(!Modifier.isFinal(clazz.getModifiers())) | |
for(Constructor<?> each : clazz.getConstructors()) | |
if(each.getParameterTypes().length == 0) | |
return true; | |
return false; | |
} | |
@Inherited | |
@Target(ElementType.METHOD) | |
@Retention(RetentionPolicy.RUNTIME) | |
public static @interface Concurrent { | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment