Skip to content

Instantly share code, notes, and snippets.

@lzxz1234
Last active September 23, 2016 12:24
Show Gist options
  • Save lzxz1234/d07b786414b93ea6734d945bdc1e7880 to your computer and use it in GitHub Desktop.
Save lzxz1234/d07b786414b93ea6734d945bdc1e7880 to your computer and use it in GitHub Desktop.
Lang
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&lt;Bid>
* @param collectProp id
* @return List&lt;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