Java:如何使用不同的equals定义执行列表操作?
Java:如何使用不同的equals定义执行列表操作 我有两个通用POJO列表。我需要根据比较列表中POJO的不同方式对列表执行一些set操作 例如,如果我的POJO具有以下结构:Java:如何使用不同的equals定义执行列表操作?,java,list,comparator,Java,List,Comparator,Java:如何使用不同的equals定义执行列表操作 我有两个通用POJO列表。我需要根据比较列表中POJO的不同方式对列表执行一些set操作 例如,如果我的POJO具有以下结构: public class GenericPojo { private String id; private String address; private String city; private String country; private String extraDeta
public class GenericPojo {
private String id;
private String address;
private String city;
private String country;
private String extraDetails;
}
(使用适当的getter和setter)
给定List1
和List2
,我将如何找到:
List1-List2(如果ID相等,GenericPojo
类相等)
列表1和列表2相交(其中id
,地址
,城市
,国家
,但通用POJO的额外细节
不相等)
两个不同的自定义比较器类在这里有用吗?是否有任何库可以有效地处理这些操作,或者我应该尝试实现我自己的操作?如果您的列表不包含重复项(使用假设的自定义比较器类的repsect),您可以使用两个树集,分别用两个比较器实例化
这种方法的一个缺点(除了复制约束)是,迭代元素时得到的顺序取决于比较器。鉴于您对等式的具体要求,而且不适合您的需要,因此我认为您需要一个自定义实现来执行与这两个操作类似的操作。没有一个解决方案符合列表契约,并且列表的现有实现都不允许您提供比较器。列表契约根据每个元素的equals(Object)
方法定义列表的行为
如果比较器的compare
方法与每个元素的equals(Object)
方法不一致,则使用不同比较器的树集的建议也违反了合同
实际上,您可能需要实现自己的列表类。您可以使其成为一个不严格遵循列表契约的列表实现,但您需要注意,这不会破坏其他库方法/类。如果您不想自己编程设置操作,也不介意浪费一些CPU和内存资源,您可以:
- 基于您的
GenericPojo
s构建WrappedPojo
s
- 给出
WrappedPojo
适当的equals()实现
- 创建适当类型的
WrappedPojo
的新列表,以便对其执行操作
- 操作完成后,将包含的
GenericPojo
s复制回其原始容器(如果需要)
丑陋但简单。您可以通过以下方法将所有这些保留在域对象中:
仅基于id
在GenericPojo
上实现等于(
…)
根据附加的GenericPojo
字段,将WrappedPojo
定义为GenericPojo
的包装,并使用等于(
…)
)
对于第二个用例,使用包装实例的列表
我建议根本问题是试图拥有一个具有不同相等定义的单一域类。如果您必须在无法控制的情况下操纵类,我建议使用委托。以下是我的尝试:
创建一个RichList
包装器,围绕List
s,基于
创建一个EqualityChecker
interface,使用一个方法“publicbooleanequal(t1,T,t2)”
为通用pojo实现此接口两次:一次只检查ID,另一次检查其他字段
添加您感兴趣的两种方法(set substraction和set intersection),但添加一个补充参数,即EqualityChecker
将为您执行相等测试的具体实例
因此,您可以将这两个操作添加到任何类型对象的所有现有列表
s中,您已经为这些对象编写了EqualityChecker
进一步的改进:您还可以编写一个默认的EqualityChecker
,它只调用比较对象的equals方法。然后,您可以重载这两个新操作,以默认EqualityChecker
您尝试执行的两个操作都是功能性的,尽管Java不太支持这些操作,您可能会以非常不同的方式编写它们。
为了适应java,您可能需要重新思考您试图实现的目标
您所做的是对数据类型的投影执行操作(即,对于字段子集)
您正在使用的操作也是设置操作,而不是列表操作。e、 g.您不能将两个列表相交(或者至少您必须定义这意味着什么),Remove也可能无法完全按照您对列表的预期执行
假设您有一个方法,它返回一个POJO集合,其中只包含您指定的字段。过去,我编写了一个库来高效地使用动态生成的类来实现这一点,看看functional Java或类似的东西
public static <Pojo, Pojo2> Set<Pojo2> project(Collection<Pojo> collection,
String... fieldsToRetain);
公共静态集项目(集合,
字符串…字段存储);
List1-List2(其中,如果ID相等,则GenericPojo类相等)
Set setOfIds=project(列表1,“id”)
项目(列表2,“id”);
列表1和列表2的交集(其中id、地址、城市、国家,但不包括GenericPojo的额外详细信息)
Set intersection=项目(列表1,“id”、“地址”、“城市”、“国家”);
交叉口保留(项目(列表2,“id”、“地址”、“城市”、“国家”);
这是我的第一个问题,如果我有任何风格错误或其他错误,请编辑并让我知道我做了什么
Set<PojoWithId> setOfIds = project(list1, "id")
setOfIds.retainAll(project(list2, "id"));
Set<PojoWithThreeFields> intersection = project(list1, "id", "address", "city", "country");
intersection.retainAll(project(list2, "id", "address", "city", "country"));