我正在开发一个具有切换帐户功能的网络应用。当您单击切换帐户链接时,会出现一个带有下拉列表的框,其中包含您可以切换到的所有帐户的列表。
如果用户只有两个帐户,我打算不显示包含下拉列表的框,而只是切换到另一个帐户。
这很容易做到,但获取“其他帐户”的代码并不是非常优雅。我希望有人有想法清理它。
public boolean hasExactlyTwoAccounts() {
return this.accountIdMap.size() == 2;
}
/**
* @return the account Id that is not currently selected
*/
public String getOtherAccountId() {
assert this.hasExactlyTwoAccounts();
for (String accountId : accountIdMap.keySet()) {
if (!this.selectedAccountId.equals(accountId)) {
return accountId;
}
}
// worst case scenario
return selectedAccountId;
}
我很少使用断言,但在这里确实合适。这些方法是从JSP调用的,只有在hasExactlyTwoAccounts()方法为true时才调用getOtherAccountId()方法。所以在这里使用assert只是为了将来另一个使用它的开发人员不正确地证明这个方法。
有人想到吗?首先,以更优雅的方式获取地图中的另一个键,其次,我使用断言和断言。
编辑我愿意使用外部库......这就是我所说的优雅。
答案 0 :(得分:1)
我认为您获取其他帐户ID的方法非常精细且易于理解。其他方法可能不太清晰,效率较低(创建其他集合等)。
我实际上甚至说没有使用第三方库就没有更优雅的解决方案,至少不会过分。即使使用第三方库(例如番石榴),解决方案也不会有任何优势,并且可能效率较低(例如,过滤设定差异的集合)。
如果没有找到其他帐户ID(最坏的情况),您应该考虑的更改是抛出异常。断言应该注意这一点,但是不需要你的最坏情况返回(除了使代码可编辑)。我建议用抛出的异常替换它。
编辑:
既然你提到你对外部库是开放的,那么这可能是使用Google Guava的代码最少的解决方案(不一定是最优雅的):
Sets.filter(accountIdMap.keySet(), Predicates.not(Predicates.equalTo(selectedAccountId))).iterator().next();
这是否被认为是优雅的,几乎是一个意见问题,我实际上并不确定我的立场。
答案 1 :(得分:1)
对断言没有任何意见,但是一个问题:在这里对未申请的断言的应用会产生什么影响,这是你想要的吗?有时最好记录错误以供日后查看,并给出一个合理的答案,让程序继续前进。
这是一个单行程序,它返回哈希中的“其他”键。它删除你不想要的密钥,然后返回剩余的密钥。它在删除之前复制哈希;这就是{} .update(hash)的用途。由于删除不返回哈希值,因此使用tap来将所有内容保存在一行中。
1.9.3-p429 :001 > hash = {a: 1, b: 2}
=> {:a=>1, :b=>2}
1.9.3-p429 :002 > {}.update(hash).tap{|h|h.delete(:a)}.keys[0]
=> :b
1.9.3-p429 :003 > hash
=> {:a=>1, :b=>2}
1.9.3-p429 :004 >
顺便说一下,你可能比你需要的更多地使用“这个”。
答案 2 :(得分:0)
我认为这看起来好多了
/**
* @return the account Id that is not currently selected
*/
public String getOtherAccountId() {
if(!this.hasExactlyTwoAccounts()) {
throw new IllegalStateException("You cannot call this method if the accountIdMap is not a size of 2");
}
Set<String> accountIds = new HashSet<String>(this.accountIdMap.keySet());
accountIds.remove(this.selectedAccountId);
return accountIds.iterator().next();
}