我知道各位会说换其他 Java 替代语言(Kotlin...),但是公司代码库暂时不支持。
现在我有一堆User
, 然后有个 Helper 会逐个检查这些 User,然后如果 User 的 Email 地址或者电话号码对应输入,就 return 那个 User。代码如下(手工重写的,省去了很多细节)
public User getUserFromEmail(String email) {
for (User user : getUsers()) {
if (email.equals(user.getEmail())) {
return user;
}
}
}
public User getUserFromPhoneNumber(String phoneNumber) {
for (User user : getUsers()) {
if (phoneNumber.equals(user.getPhoneNumber())) {
return user;
}
}
}
那这俩方程基本就差一点点,所以我想把他们合并起来。我现在的想法写出来感觉非常恶心。
public User getUserFromEmail(String email) {
User(email, null);
}
public User getUserFromPhoneNumber(String phoneNumber) {
getUser(null, phoneNumber);
}
private User getUser(String email, String phoneNumber) {
String query, userInfo;
if (email != null) {
query = email;
} else if (phoneNumber != null) {
query = phoneNumber;
} else {
return null;
}
for (user : getUsers()) {
if (email != null) {
userInfo = user.getEmail();
} else if (phoneNumber != null) {
userInfo = user.getPhoneNumber();
}
if (query.equals(userInfo)) {
return user;
}
}
}
蛋疼的地方有 2 个,一个是合并后结果比原来长很多,还有一个是这样每个循环都要做多一个 check,显得非常愚蠢,不知道各位 Java 大佬有没有什么办法可以帮到我,先谢谢了 ><
1
hyyou2010 2017-12-05 11:52:17 +08:00
定义这么个东西:
public class UserCompareItems{ public String name;//为 null 时表示不必对这一项 public String phone;//非 null 时表示比对这一项 public String otherItems; } 然后在 User 类中实现一个和 UserCompareItems 比较的接口 以后只传这个类的对象来挑选 user ----------临时想的,没验证,不一定好,仅供参考 |
2
cloud107202 2017-12-05 11:52:48 +08:00
这个算是 OO 语言给思维带来的枷锁。试图从 List 中 filter 一些结果,但是要根据不同的动态条件。纯 OO 语言里不太好做,或者需要动用设计模式。FP 里就是把怎样取属性并比较这个动作(function/ first-class function ) 当成变量传进去而已。
举个例子,边界判断要自己补充下 https://gist.github.com/liyuntao/54bc04e963fa969b2d82903d51bfea69 |
3
SuperMild 2017-12-05 12:16:21 +08:00 via iPhone
电话号码不可能含 @ ,判断一下字符就可以自动选择不同的流程了
|
4
SuperMild 2017-12-05 12:18:44 +08:00 via iPhone
增加一个叫 getFromEmailOrPhonenumber 的 wraper
|
5
20015jjw OP @cloud107202
你的想法我挺喜欢,但是 Java 还不支持,所以很痛苦... 我大概实现了一个类似的,但是无奈效果还是感觉不如原来的,因为还是比原来的长,而且比原来的难读很多。谢谢了。 @hyyou2010 welp,简直蛋疼... 如果就 email 和电话感觉远不要这么麻烦。 |
6
marknote 2017-12-05 12:29:38 +08:00 via iPhone
用 lambda 吧
|
7
20015jjw OP @SuperMild 我也想到了,但感觉虽然这里可以用,但是换一种情况就又蛋疼了... 而且还是少不了每次循环的电话 /邮箱 check...
``` for (...) { if (query.is_number && query.equals(User.getPhoneNumber()) { return user; } else if (query.is_email && query.equals(User.getEmail()) { return user; } } ``` |
8
canbingzt 2017-12-05 13:01:57 +08:00
直接 query.equals(user.getEmail()) || query.equals(user.getPhoneNumber()) 就可以了吧
邮箱和电话号码应该不会相同吧 |
9
zjp 2017-12-05 13:18:13 +08:00 via Android
如果还有更多属性需要查找,#2 的行为模版化的方法就能体现出优势来 只是没有 lambda 写起来更长了…
|
10
cloud107202 2017-12-05 13:22:22 +08:00
@20015jjw 给你的代码就是 java8 的 lambda API...
|
11
SoloCompany 2017-12-05 13:25:15 +08:00 via iPhone
实在用不了 j8 还可以用 org.apache.common-collections 顶一下,别想可以有多大改进,只是换一种抽象( functor 或说算子)而已
|
12
kran 2017-12-05 13:37:38 +08:00 via iPhone
用反射,传字段名和值
|
13
kx5d62Jn1J9MjoXP 2017-12-05 14:44:36 +08:00
自定义一个 Interface
interface Matcher { boolean matches(User user); } 通用方法 User getUser(Matcher matcher) { for (User user : getUsers()) { if (matcher.matches(user) return user; } return null; } 这是很基本的东西, 上面有人说用 lamda 也好用 stream api 的 filter 也好都是同一个道理 这种东西在 Java 里面到处都有 |
14
LxExExl 2017-12-05 14:51:39 +08:00 via iPhone
没写过 java
PHP 的话有 schema 直接 queryFrom 然后 whereEquals... 帮顶了 |
15
evitceted 2017-12-05 15:13:16 +08:00
rxjava
|
16
20015jjw OP @cloud107202 我的意思是 java 8 不能用 很难受...
@ssynhtn 对这个也很难读 我想到了但是写出来不可能比那俩原方程短了 @SoloCompany 一会看看 谢谢 但是我觉得可能 @canbingzt 的办法暂时就够了 没想到这个 hhhh 谢谢啦 |
17
yrom 2017-12-05 17:25:41 +08:00
android studio 3.0 已经支持 java 8 部分特性了(尤其是 lambda )
|
18
YellowLittleDog 2017-12-05 18:20:22 +08:00 via Android
rxjava 链起来
|
19
20015jjw OP |