1

我正在开发一个具有切换帐户功能的网络应用程序。当您单击切换帐户链接时,会出现一个带有下拉列表的框,其中列出了您可以切换到的所有帐户。

对于用户恰好有两个帐户的情况,我打算不显示带有下拉菜单的框,而只是切换到另一个帐户。

这确实很容易做到,但是获取“其他帐户”的代码并不是很优雅。我希望有人有一个想法来清理它。

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 只是为了将来证明另一个开发人员不正确地使用了这个方法。

有人想吗?首先,关于获取地图中另一个键的更优雅的方式,其次,关于我对断言和一般断言的使用。

编辑我对使用外部库持开放态度......这几乎就是我所说的优雅。

几乎是这样的:http: //grepcode.com/file/repo1.maven.org/maven2/com.github.ansell.pellet/pellet-common/2.3.3/org/mindswap/pellet/utils/BinarySet.java

4

3 回答 3

1

我认为您获取其他帐户 ID 的方法非常好并且易​​于理解。其他方法可能不太清晰且效率较低(创建其他集合等)。

实际上,我什至会说没有更优雅的解决方案,至少不会过度,而不使用 3rd 方库。即使使用 3rd 方库(例如 Guava),该解决方案也不会真正有任何优越性,并且可能效率较低(例如过滤取集合差异的集合)。

如果没有找到其他帐户 ID(最坏的情况),您应该考虑的唯一更改是抛出异常。断言应该解决这个问题,但是不需要返回最坏的情况(除了使代码可编译)。我建议用抛出的异常替换它。

编辑:

既然您提到您对外部库开放,那么这可能是使用 Google Guava 代码行数最少的解决方案(但不一定是最优雅的):

Sets.filter(accountIdMap.keySet(), Predicates.not(Predicates.equalTo(selectedAccountId))).iterator().next();

这是否被认为是优雅的,这在很大程度上是一个见仁见智的问题,我实际上不确定我的立场。

于 2013-07-24T17:31:46.480 回答
1

对断言没有意见,但有一个问题:在这里应用未捕获的断言会对您的应用产生什么影响,这是您想要的吗?有时最好记录一个错误以供以后查看,并给出一个合理的答案,让程序继续前进。

这是一个单行代码,它返回哈希中的“其他”键。它会删除您不想要的密钥,然后返回剩余的密钥。它在删除之前复制哈希;这就是 {}.update(hash) 的用途。由于 delete 不返回哈希值,因此 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 > 

顺便说一句,您可能比您需要的更多地使用“this”。

于 2013-07-24T17:31:56.307 回答
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();
}
于 2013-07-24T17:29:51.453 回答