检查地图中所有的值是否相等

4

我需要检查一个map中的所有值是否相等。我有一个执行此任务的方法,但想使用库或本地方法。限制:Java 5+Apache Commons库。

public static boolean isUnique(Map<Dboid,?> aMap){

boolean isUnique = true;
Object currValue = null;
int iteration = 0;

Iterator<?> it = aMap.entrySet().iterator();

while(it.hasNext() && isUnique){
    iteration++;
    Object value = it.next();
    if(iteration > 1){
        if (value != null && currValue == null ||
            value == null && currValue != null ||
            value != null && currValue != null & !value.equals(currValue)) {
            isUnique = false;
        }
    }
    currValue = value;
}
return isUnique;
}

你可以改进自己的方法。a_horse_with_no_name建议的代码可以完成任务,但它会创建一个单独的HashSet,并在此过程中复制可能所有的值到该HashSet中。 你只需要获取第一个元素并将其与所有其他元素进行比较(foreach循环在这里非常有用),直到找到一个不等于第一个元素值的元素为止。一旦找到不相等的元素,就可以跳出循环。 - Germann Arlington
6个回答

15

这个东西怎么样:

Set<String> values = new HashSet<String>(aMap.values());
boolean isUnique = values.size() == 1;

那对于许多不唯一的元素来说,这种方法无法很好地扩展。 - David Ehrmann
@KevinBowersox 那么它们显然不相等。 - Hunter McMillen
@DavidEhrmann:我想这不会比问题中的代码更慢。 - user330315
也许 values.size() <= 1 更好。我认为空映射也可以被视为一种解决方案。 @DavidEhrmann:根据equals()hashCode()的实现方式,它可能非常慢。 - NeplatnyUdaj
@NeplatnyUdaj:我也考虑过这个问题,但我认为最好在方法中设置一个 if (aMap.isEmpty()) return true 的前置条件。 - user330315
@a_horse_with_no_name 慢一些,但是它占用的内存比实际需要的多很多。 - David Ehrmann

2
如何?
return (new HashSet(aMap.values()).size() == 1)

2

我知道原问题要求使用Java 5的解决方案,但是如果其他人在寻找答案时不受Java 5的限制,这里提供了一种Java 8的方法。

return aMap.values().stream().distinct().limit(2).count() < 2

1
如上面我的评论所述:
//think in a more proper name isAllValuesAreUnique for example
    public static boolean isUnique(Map<Dboid,?> aMap){
         if(aMap == null)
               return true; // or throw IlegalArgumentException()

         Collection<?> c = aMap.getValues(); 
         return new HashSet<>(c).size() <= 1;
    }

1
public static boolean isUnique(Map<Dboid,?> aMap) {
    Set<Object> values = new HashSet<Object>();

    for (Map.Entry<Dboid,?> entry : aMap.entrySet()) {
      if (!values.isEmpty() && values.add(entry.getValue())) {
        return false;
      }
    }

    return true;
}

如果地图中存在许多差异,这种解决方案具有节省内存的优势。对于空的Map特殊情况,您可以选择将返回值更改为false,并根据需要进行适当更改。

如果您的Map不包含null值,则甚至可以在没有Set的情况下更好地完成:

public static boolean isUnique(Map<Dboid,?> aMap) {
    Object value = null;

    for (Object entry : aMap.values()) {
      if (value == null) {
        value = entry;
      } else if (!value.equals(entry)) {
        return false;
      }
    }

    return true;
}

1
你可以将值存储在双向映射中,这样就能始终拥有此属性。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接