我有多个功能可根据条件过滤对象地图。
函数具有相同的主体,只有布尔传递条件才会改变。
filterOnFirstCriteria(Criteria criterias, Map<Integer, List<Container>> containerMap, Map<Integer, ClassKey> classKeys) {
for (Map.Entry<Integer, List<Container>> entry : containerMap.entrySet()) {
List<Container> containers = entry.getValue();
ClassKey classKey = classKeys.get(entry.getKey());
for (Container container : containers) {
List<MyObject> found = new ArrayList<>();
for (MyObject myObject : container.getMyObjects()) {
boolean pass = criterias.getListOfFilter().stream().filter(s -> s.equals(container.getReference())).count() > 0;
if (pass) {
found.add(myObject);
}
}
container.getMyObjects().removeAll(found);
}
}
}
filterOnOtherCriteria(Criteria criterias, Map<Integer, List<Container>> containerMap, Map<Integer, ClassKey> classKeys) {
for (Map.Entry<Integer, List<Container>> entry : containerMap.entrySet()) {
List<Container> containers = entry.getValue();
ClassKey classKey = classKeys.get(entry.getKey());
for (Container container : containers) {
List<MyObject> found = new ArrayList<>();
for (MyObject myObject : container.getMyObjects()) {
boolean pass = myObject.getListOfObject().stream().filter(obj -> criterias.getLocations().stream().anyMatch(location -> location.equals(obj.getLocation()))).count() > 0;
if (pass) {
found.add(myObject);
}
}
container.getMyObjects().removeAll(found);
}
}
}
条件可以来自上层循环的任何对象。 我想将重复的循环代码提取到函数中,但我不知道如何为布尔条件传递某种回调。
谢谢。
答案 0 :(得分:3)
两种方法的唯一区别是陈述:
boolean pass = criterias.getListOfFilter().stream()
.filter(s -> s.equals(container.getReference()))
.count() > 0;
和
boolean pass = myObject.getListOfObject().stream()
.filter(obj -> criterias.getLocations().stream()
.anyMatch(location -> location.equals(obj.getLocation())))
.count() > 0;
第一个语句不依赖于从内循环获取的myObject
,而是依赖于从外循环获取的container
。它还取决于传递给方法的参数criterias
。
第二个语句取决于从内循环和传递给方法的参数myObject
获取的criterias
。
因此,如果您想重构那些产生boolean
的语句,您必须找到支持这两种语句的统一方法:
@FunctionalInterface
public interface Guardian {
boolean pass(MyObject myObject, Container container);
}
现在您已准备好提取这两个语句并将它们作为lambdas传递给您的新方法:
public static void filterOnFirstCriteria(Criteria criterias, Map<Integer, List<Container>> containerMap, Map<Integer, ClassKey> classKeys) {
filterOn(criterias, containerMap, classKeys, (myObject, container) ->
criterias.getListOfFilter().stream()
.filter(s -> s.equals(container.getReference()))
.count() > 0);
}
public static void filterOnOtherCriteria(Criteria criterias, Map<Integer, List<Container>> containerMap, Map<Integer, ClassKey> classKeys) {
filterOn(criterias, containerMap, classKeys, (myObject, container) ->
myObject.getListOfObject().stream()
.filter(obj -> criterias.getLocations().stream().anyMatch(location -> location.equals(obj.getLocation())))
.count() > 0);
}
public static void filterOn(Criteria criterias, Map<Integer, List<Container>> containerMap, Map<Integer, ClassKey> classKeys, Guardian guardian) {
for (Map.Entry<Integer, List<Container>> entry : containerMap.entrySet()) {
List<Container> containers = entry.getValue();
ClassKey classKey = classKeys.get(entry.getKey());
for (Container container : containers) {
List<MyObject> found = new ArrayList<>();
for (MyObject myObject : container.getMyObjects()) {
if (guardian.pass(myObject, container)) {
found.add(myObject);
}
}
container.getMyObjects().removeAll(found);
}
}
}