假设我有一个类Person
(假设所有属性都可以设置,也可以为null):
public class Person {
private String firstName;
private String secondName;
private Address address;
public String getFirstName() { return firstName; }
public String getSecondName() { return secondName; }
public String getAddress() { return address; }
}
字符串
如果我有两个Person
的示例,我想检查它们是否都有相同的firstName
和secondName
,我不能简单地调用equals()
,因为这也会检查address
是否相等(以及任何其他属性)。
我需要写一个这样的函数:
boolean areNamesEqual(Person person1, Person person2) {
if(person1 == null || person2 == null) {
return person1 == person2;
}
if(person1.getFirstName() != null ? !person1.getFirstName().equals(person2.getFirstName()) : person2.getFirstName() != null) {
return false;
}
if(person1.getSecondName() != null ? !person1.getSecondName().equals(person2.getSecondName()) : person2.getSecondName() != null) {
return false;
}
return true;
}
型
有没有更清楚的方式来表达这一点?感觉Java为了表达这个简单的想法,似乎跳过了很多圈。我已经开始研究Google Guava,并发现我可以使用Objects.equal()
来改善问题:
boolean areNamesEqual(Person person1, Person person2) {
if(person1 == null || person2 == null) {
return person1 == person2;
}
if(Objects.equal(person1.getFirstName(), person2.getFirstName())) {
return false;
}
if(Objects.equal(person1.getSecondName(), person2.getSecondName())) {
return false;
}
return true;
}
型
但是我仍然必须检查Person对象本身是否为null,并分别写入getFirstName()和getSecondName()两次。我觉得应该有更好的方式来表达这一点。
像这样的代码是理想的:
(person1, person2).arePropertiesEqual(firstName, secondName)
型
有了这个,我就不用在任何地方检查null了,我不必提前返回,我也不必多次写入firstName
或secondName
。
有什么想法吗
6条答案
按热度按时间5lwkijsr1#
使用Java(至少在Java 8和lambdas之前)和Guava,你不会走得太远,因为Java不是一种函数式语言。请参阅Guava Wiki中的Functional Explained中的注意事项部分以获得额外的意见。
实际上,您可以做到这一点,但需要付出更多代码的代价,因此您应该真正评估是否需要它。类似于:
字符串
注意:我既没有编译也没有运行上面的代码,由于使用了泛型数组(在varargs中),它可能至少有警告。
在Java 8中,它已经更短了,看起来像这样:
型
注意这里使用的是
java.util.Objects
和java.util.functions.Function
,而不是Guava。现在,这真的比命令式代码“更好”吗?
cuxqih212#
下面是你的函数的一个稍微短一点的版本:
字符串
xesrikrc3#
试试这个:
字符串
否则,您可以使用Objects.equal。
型
所有其他属性都一样。
tpgth1q74#
有一个pojomatic API不需要添加太多代码。http://www.pojomatic.org/pojomatic/index.html
之前的例子中,你只需要对pojo使用autoproperty进行注解,对策略为'Equals'的字段使用@property进行注解
字符串
现在当你说person1.equals(person 2)时,只考虑名字和最后一次
yizd12fk5#
您还可以通过反射使用一些更动态的东西,如下所示。
字符串
使用示例:
型
wmomyfyw6#
不太想没有更好的方式来表达这一点。“有了这个,我就不用在任何地方检查null了”--好吧,检查null是一个要求,这太糟糕了。我不知道为什么你必须检查null是否等于它自己,或者null是否等于一个Person的名字,或者为什么人们用null而不是名字。这一切对我来说似乎都是无稽之谈,但你可能有一个很好的理由。
您无法避免使用比已经编写的代码更少的代码重复firstName和lastName的访问器。如果你把这个方法放在Person类本身上,你至少应该能够通过直接使用私有字段来避免“get”和“()”。下面是一些代码,并不比你的问题中的代码更好:
字符串