我正在为大学布置家庭作业,它不允许我更改类(class)的属性。我为搜索方法想出了以下代码,但我不禁注意到了重复的代码。我需要构建两种搜索方法。搜索 ArrayList<Person>
的一个和一个搜索 ArrayList<Module
的.两者 Person
和 Module
有一个String name
属性(property)。
public static <T extends Person> ArrayList<T> findPerson(List<T> list, String query) {
ArrayList<T> matching = new ArrayList<>();
list.forEach(s -> {
if (s.name.contains(query)) matching.add(s);
});
return matching;
}
public static <T extends Module> ArrayList<T> findModule(List<T> list, String query) {
ArrayList<T> matching = new ArrayList<>();
list.forEach(s -> {
if (s.name.contains(query)) matching.add(s);
});
return matching;
}
是否可以在不改变类结构的情况下组合这些方法?我沿着这些方向尝试了一些东西,但它似乎仍然不起作用:(方法签名中的不同类型参数)
public static <T extends Person, Module> ArrayList<T> findModule(List<T> list, String query) {
ArrayList<T> matching = new ArrayList<>();
list.forEach(s -> {
if (s.name.contains(query)) matching.add(s);
});
return matching;
}
编辑:这里是类:
public abstract class Person extends TableItem {
public String name, famName, street, zip, city;
public String[] data = new String[7];
...
}
public class Module extends TableItem {
private Manager manager;
public String[] data = new String[5];
public String name, nr, profID, semester, part;
public ArrayList<String> participants;
...
}
public abstract class TableItem {
public abstract String getString();
public abstract void updateData();
}
最佳答案
理想情况下,您让两个类都实现相同的接口(interface),例如 NamedItem
这将有一个功能 getName()
,它会简单得多,因为你让你的函数采用 List<? extends NamedItem>
.如果这不可能,您将必须提供 Function
确定什么String
匹配的属性。
public static <T> List<T> find(List<T> list, String query, Function<T, String> keyExtractor) {
return list
.stream()
.filter(s -> keyExtractor.apply(s).contains(query))
.collect(Collectors.toList());
}
然后你可以像这样使用它:
List<Person> matchingPersons = find(allPersons, query1, Person::getName);
List<Module> matchingModules = find(allModules, query1, Module::getName);
您可以将它用于任何属性,而不仅仅是名称。您只需传递提取 String
的函数你想作为第三个参数匹配。
关于java - 是否可以结合这些方法? (Java泛型),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54484792/