java - 按对象类型的字段值搜索重复项在列表中
问题描述
我不确定我的问题是否清楚,但我试图在列表中查找重复的对象,如果它们在具有相同值的对象中有 1 个或多个字段,则它们是重复的。我还试图使其对许多数据类具有通用性和可重用性。
这是我刚刚提出的解决方案。如果发现重复,则返回 true,否则返回 false。这个解决方案好吗?或者还有什么我可以用来实现我的目标的吗?
(编辑为忽略空值)
public class TestObject {
private String str;
public TestObject(String str){
this.str = str;
}
}
public static <T> boolean checkForDuplicateByFields(List<T> ls, String... fieldNames) {
if (ls == null || ls.isEmpty()) {
return false;
}
//create hashset of <fieldName, values>
HashMap<String, HashSet<Object>> map = new HashMap<>();
for (String name : fieldNames) {
map.put(name, new HashSet<>());
}
// Search for duplicates of fields' value in list <T>
for (String name : fieldNames) {
try {
Field f = ls.get(0).getClass().getDeclaredField(name);
f.setAccessible(true);
for (T obj : ls) {
try {
HashSet<Object> names = map.get(name);
Object o = f.get(obj);
if(o == null){
continue;
}
if (names.isEmpty()) {
names.add(o);
} else if (names.contains(o)) {
return true;
}
} catch (IllegalAccessException ex) {
break;
}
}
} catch (NoSuchFieldException ex) {
break;
}
}
return false;
}
public static void main(String[] args){
List<TestObject> ls = new ArrayList<>();
TestObject obj = new TestObject("hello");
ls.add(obj);
ls.add(obj);
System.out.println(checkForDuplicateByFields(ls, "str"));
}
解决方案
考虑到每个字段都有 getter 方法,我认为您可以使用 lambda 和功能接口以更简洁的方式完成此操作。
考虑以下示例:
public class App
{
public static void main( String[] args )
{
Student s = new Student(100,"xyz");
Function<Student,Integer> studentRNMapper = ((student) -> student.getRollNumber());
System.out.println(studentRNMapper.apply(s)); // print 100
Function<Student,String> studentNameMapper = ((student) -> student.getName());
System.out.println(studentNameMapper.apply(s)); // print "xyz"
}
}
class Student {
private Integer rollNumber;
private String name;
public Student(Integer rollNumber,String name) {
this.rollNumber = rollNumber;
this.name = name;
}
public Integer getRollNumber() {
return rollNumber;
}
public String getName() {
return this.name;
}
}
您可以考虑传递功能接口,而不是传递字段名称。这样您就不必使用反射 API。在你的情况下,它看起来像这样:
TestObject obj = new TestObject("hello");
ls.add(obj);
ls.add(obj);
Function<TestObject,String> testStrMapper = ((TestObject) -> TestObject.getStr());
System.out.println(checkForDuplicateByFields(ls, testStrMapper);
在您的 checkForDuplicateByFields 中,您将检索如下值:
testStrMapper.supply(ls.get(i)) <-- Return value of str field for the ith object.
推荐阅读
- javascript - 标识符“reducer”已声明
- c++11 - C++ 入门 5 版:shared_ptr 的容器
- matrix - 如何创建关系矩阵?
- python - __dir__ 提供循环引用,但 dir() 可以
- javascript - 如何从一个组件发布事件并从 nativescript 中的另一个组件接收它
- reactjs - React - 检查用户选择图像的尺寸
- node.js - 使用访问令牌和刷新令牌保持身份验证
- python - 可以在python中获得“地址值”吗?
- regex - 在正则表达式的开头需要 http:// 或 https://
- windows - 如何让 Clangd 在 Windows 上与 VS Code 一起正常工作