2014-06-29 45 views
1

在这个问题中,我必须有一个包含键和字符串值的映射,以查看多个键映射到相同的值。换句话说,如果没有两个键映射到相同的值,那么我的方法应该返回true。我试图解决这个问题的方法是将所有地图放入一个集合中,并检查每个元素以查看是否有相同值的两个副本;但是,这似乎并没有为我工作。任何建议将不胜感激,谢谢。查找多个键映射到相同的值

提示:

写一个接受字符串的字符串作为参数的地图,如果没有两个键映射到相同的值(和假如有两个或更多个键也映射到返回true的方法isUnique设置相同的值)。例如,调用你的方法在下面的映射将返回true:

{马蒂=斯特普,斯图尔特= Reges,杰西卡=米勒,阿曼达=营,哈尔=帕金斯}

调用它下面的地图上会返回false,因为两个映射的帕金斯和Reges的:

{肯德里克=帕金斯,斯图尔特= Reges,杰西卡=米勒,布鲁斯= Reges,哈尔=帕金斯}

空地图被认为是独一无二的,所以你的方法应该返回true,如果传递一个空的地图。

我尝试:

public static boolean isUnique(Map<String, String> input) { 
    Collection<String> values = input.values(); // stores all the values into a collection 

    for (String names: values) { // goes through each string to see if any duplicates 
     Iterator<String> wordList = values.iterator(); // iterates words in values collection 
     int repeat = 0; // counts number of repeats 
     // goes through each elem to compare to names 
     if (wordList.hasNext()) { 
      if (wordList.next().equals(names)) { 
       repeat++; 
      } 
     } 
     if (repeat > 1) { // if more than one copy of the value exists = multiple keys to same value 
      return false; // If multiple copies of same value exists 
     } 
    } 
    return true; // all unique values 
} 

回答

1

如果我明白你的问题,那么我会一般性地实现你的方法,像这样 -

public static <K, V> boolean isUnique(Map<K, V> input) { 
    if (input == null || input.isEmpty()) { 
    return true; 
    } 
    Set<V> set = new HashSet<V>(); 
    for (V value : input.values()) { 
    set.add(value); 
    } 
    return set.size() == input.size(); 
} 
+0

难道我们不会将值放入HashSet而不是键中,因为我们试图找到重复的映射,所以HashSet可以摆脱? –

+0

@JackL。我将重复值放入'Set'中。 'input.get(key)'返回一个'V'值。 –

+0

我现在看到它;我的错。 –

1

一种解决方案可以通过地图迭代过程中,你可以存储在组字符串的值。因此,如果原始地图和设置的大小相同,则没有映射到两个或更多地图键的值。

至于执行得好,这是可以做到如下:

public boolean checkMap(Map<String, String> map) { 
    Set<String> set = new HashSet<String>(); 

    for(Entry<String, String> entry:map.entrySet()) { 
     set.add(entry.getValue); 
    } 

    if(map.size == set.size) 
     return true; 

    return false; 
} 
1

的捷径我可以想到这样做是

public static boolean valuesAreUnique(Map<K,V> input) { 
    Collection<V> values = input.values(); 
    return (new HashSet<V>(values)).size() == values.size(); 
} 

但是,它不是最高性能的方式o f这样做,因为它建立了这个集合,即使在找到重复之后它也会继续添加元素。因此,如果您执行以下操作,它很可能会表现更好,它利用Set接口的add方法的返回值。

public static boolean valuesAreUnique(Map<K,V> input) { 
    Set<V> target = new HashSet<V>(); 
    for (V value: input.values()) { 
     boolean added = target.add(value); 
     if (! added) { 
      return false; 
     } 
    } 
    return true; 
} 
+0

这是一个很酷的方式。我不知道add方法有返回值。由于列表接口有几乎相同的常用方法集,它是否也为列表返回值? –

+0

嗯,是的,'add'方法对'List'确实有一个返回值,但它不是很有用,因为它总是'true',因为List允许包含重复项。 –

1

Shrikant Kakani's和Elliott Frisch的方法是正确的。但是,我们可以让它更有效的通过停止迭代,一旦我们发现重复:

public static boolean isUnique(Map<String, String> input) { 
    Set<String> uniqueValues = new HashSet<String>(); 
    for (String value : input.values()) { 
    if (uniqueValues.contains(value)) { 
     return false; 
    } 
    uniqueValues.add(value); 
    } 
    return true; 
} 
+0

你可以通过使用'add'的返回值来提高效率 - 这基本上和我的答案的第二部分相同。 –

+0

@DavidWallace对不起,David。谢谢。当我写我的时候,你的回答不在那里。 – fajarkoe

0

从书中的练习特定章节,而据我了解,它预计将有一解决方案涵盖每个主题。可以理解的是,上面已经提交了多个更好的解决方案,但是给出的练习涵盖了与它们相关的地图,键,值和方法。第二次使用Value时,使用下面的方法停止。

public static boolean isUnique(Map<String, String> map){ 
     Map<String, Integer> check = new HashMap<String, Integer>(); 
     for (String v : map.values()){ 
      if (check.containsKey(v)){ 
       return false; 
      } else { 
       check.put(v, 1); 
      } 
     } 
     return true;   
    }