首先,创建自己的MethodPair 类:
class MethodPair {
private final Method failure;
private final Method normal;
public MethodPair(Method failure, Method normal) {
this.failure = failure;
this.normal = normal;
}
public Method getFailure() {
return failure;
}
public Method getNormal() {
return normal;
}
public MethodPair combinedWith(MethodPair other) {
return new MethodPair(
this.failure == null ? other.failure : this.failure,
this.normal == null ? other.normal : this.normal)
);
}
}
注意combinedWith 方法。这对我们将要做的减少很有用。
使用reducing 收集器代替toList:
Map<String, MethodPair> map = ml.stream().collect(groupingBy(m -> {
var ann = m.getDeclaredAnnotation(MyTag.class);
return ann.anId();
}, TreeMap::new,
Collectors.reducing(new MethodPair(null, null), method -> {
var type = method.getDeclaredAnnotation(MyTag.class).type();
if (type == Type.NORMAL) {
return new MethodPair(null, method);
} else {
return new MethodPair(method, null);
}
}, MethodPair::combinedWith)
));
如果您可以分两步执行此操作,我建议您先创建Map<String, List<Method>>,然后将其值映射到新地图。 IMO 这更具可读性:
Map<String, List<Method>> map = ml.stream().collect(groupingBy(m -> {
var ann = m.getDeclaredAnnotation(MyTag.class);
return ann.anId();
}, TreeMap::new, toList()));
var result = map.entrySet().stream().collect(Collectors.toMap(entry -> entry.getKey(), entry -> {
Method normal = null;
Method failure = null;
for (var m : entry.getValue()) {
var type = m.getDeclaredAnnotation(MyTag.class).type();
if (type == Type.NORMAL && normal == null) {
normal = m;
} else if (type == Type.FAILURE && failure == null) {
failure = m;
}
if (normal != null && failure != null) {
break;
}
}
return new MethodPair(failure, normal);
}));