在一组2中抓取“其他”值

时间:2013-07-24 17:05:11

标签: java set assert

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

如果用户只有两个帐户,我打算不显示包含下拉列表的框,而只是切换到另一个帐户。

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

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

3 个答案:

答案 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();
}