问题描述
今天学习了一下java.util.function中的几个方法,觉得很帅很优雅,于是学的过程中照搬着把我以前的
一个判断字段是否为空的代码重写了一遍(有些业务定义如果某个字段等于-1也默认认为它为空).
实现之后对照着跑了一遍,发现性能居然比原来的代码慢了十倍,所以有些疑惑,先看看代码吧:
相关代码
// 旧代码
public static boolean isBlank(T t) {
if (t == null) {
return true;
}
if (t instanceof List) {
if (((List) t).size() == 0) {
return true;
}
} else if (t instanceof Map) {
if (((Map) t).size() == 0) {
return true;
}
if (((Map) t).get("-1") != null && ((Map) t).get("-1").equals("-1")) {
return true;
}
} else if (t instanceof Set) {
if (((Set) t).size() == 0) {
return true;
}
} else if (t instanceof Object[]) {
if (((Object[]) t).length == 0) {
return true;
}
} else if (t instanceof String) {
String str = (String) t;
if (str.length() == 0)
return true;
str = str.trim();
if (str.length() == 0)
return true;
}
return false;
}
public static boolean isinFallback(T t) {
Class> c = t.getClass();
Method[] methods = c.getMethods();
try {
for (Method method : methods) {
if (method.getName().equals("getId")) {
Object o = method.invoke(t);
if (o == null) {
return true;
}
if (o.equals(-1L)) {
return true;
}
}
}
} catch (Exception e) {
e.printStackTrace();
return true;
}
return false;
}
//新代码
private static final Function filter = (s) -> {
for (Method m : s) {
if (m.getName().equals("getId")) {
return m;
} else if (m.getName().equals("getUid")) {
return m;
}
}
return null;
};
private static final Predicate object = (s) -> s.equals("-1");
private static final Function getPre = (s) -> {
if (s instanceof List) {
return (Predicate) l -> l.size() == 0;
} else if (s instanceof Map) {
return (Predicate) l -> l.size() == 0 || l.get("-1") != null;
} else if (s instanceof Set) {
return (Predicate) l -> l.size() == 0;
} else if (s instanceof Object[]) {
return (Predicate) l -> Objects.nonNull(l) && l.length == 0;
} else if (s instanceof String) {
return (Predicate) String::isEmpty;
}
return null;
};
public static boolean isBlank(T t) {
if (t == null) {
return true;
}
if (t instanceof String) {
String str = (String) t;
str = str.trim();
return getPre.apply(str).test(str);
}
Predicate apply = getPre.apply(t);
return apply != null && apply.test(t);
}
public static boolean isinFallback(T t) {
Class> c = t.getClass();
Method[] method = c.getMethods();
try {
Method apply = filter.apply(method);
return apply != null && object.or(oj -> oj.equals(-1L)).test(apply.invoke(t));
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
return false;
}
测试代码:
测试结果:
问题:
有三个方法结果不一致是因为我加了一些新的判断,所以不用在意,疑惑的地方是代码逻辑完全没有变,仅仅是把实现方法换成了java8的新实现方式,结果性能居然差了这么多.所以问题是:
1.如果是我代码写的逻辑不对导致的这个问题,那我是错在那些地方呢?
2.看方法介绍,Predicate这个类之所以存在似乎就是因为它能做一些判断性的动作,可是性能这么慢又有什么用它的必要呢?
3.如果是我杀鸡用牛刀了那么java.util.function包下的几个工具类的正确使用场景是在什么地方呢(Predicate, Consumer, Function, Supplier, UnaryOperator, BinaryOperator)?