Set <set> Java

时间:2018-06-12 11:35:32

标签: java string set equals contains

我有一个返回Set<Set<String>>的方法。在我的测试中,我尝试使用Set方法检查预期的contains()是否存在。

例如。 input = "cat", "dog", "god"

output = [[cat], [dog, god]]

现在,如果我output.contains(new HashSet<>(Arrays.asList("cat"))),则会返回true

但如果我output.contains(new HashSet<>(Arrays.asList("dog", "god"))),则返回false

根据我的理解,在两种情况下都应该返回true

我在这里缺少什么?

public class AnagramGroups {
     public Set<Set<String>> group(Set<String> words) {
         Set<Set<String>> groups = new HashSet<>();
         for(String word: words) {
             findAndAdd(word, groups);
         }
         return groups;
     }

     private void findAndAdd(String word, Set<Set<String>> groups) {
         for(Set<String> group: groups) {
             boolean found = false;
             for(String str: group) {
                 if(isAnagram(str, word)) {
                     found = true;
                 }
                 break;
             }
             if(found) {
                 group.add(word);
                 return;
             }
         }
         Set<String> set = new HashSet<>();
         set.add(word);
         groups.add(set);
     }

     private boolean isAnagram(String str, String word) {
         Set<Character> characters = new HashSet<>();
         for(char c: str.toCharArray()) {
             characters.add(c);
         }
         for(char c: word.toCharArray()) {
             if(!characters.contains(c)) {
                 return false;
             }
             characters.remove(c);
         }
         return characters.isEmpty();
     }

     public static void main(String[] args) {
         Set<Set<String>> groups = new AnagramGroups()
             .group(new HashSet<>(Arrays.asList("cat", "god", "dog")));
         System.out.println(groups);

         Set set1 = new HashSet<>(Arrays.asList("cat"));
         Set set2 = new HashSet<>(Arrays.asList("god", "dog"));
         System.out.println(groups.contains(set1));
         System.out.println(groups.contains(set2));

         groups.add(new HashSet<>(Arrays.asList("god", "dog")));
         System.out.println(groups);
     }
}

3 个答案:

答案 0 :(得分:4)

问题出在findAndAdd方法中,您正在改变外部groupSet)的元素(groups),从而更改其{{1} }}。因此,hashCode()找不到groups.contains(set2)中存在的Set,因为它在错误的存储桶(匹配新的groups)而不是存储桶中查找它添加它(与原始hashCode()匹配)。

您可以修改代码,方法是先从hashCode()移除group Set,然后再对其进行修改,然后重新添加。

更改您的代码:

groups

为:

 private void findAndAdd(String word, Set<Set<String>> groups) {
     for(Set<String> group: groups) {
         boolean found = false;
         for(String str: group) {
             if(isAnagram(str, word)) {
                 found = true;
             }
             break;
         }
         if(found) {
             group.add(word);
             return;
         }
     }
     Set<String> set = new HashSet<>();
     set.add(word);
     groups.add(set);
 }

当我尝试使用您的代码并进行更改时,我在两种情况下都获得了 private void findAndAdd(String word, Set<Set<String>> groups) { for(Set<String> group: groups) { boolean found = false; for(String str: group) { if(isAnagram(str, word)) { found = true; } break; } if(found) { groups.remove(group); group.add (word); groups.add(group); return; } } Set<String> set = new HashSet<>(); set.add(word); groups.add(set); }

输出:

true

答案 1 :(得分:0)

当您使用Set set2 = new HashSet<>(Arrays.asList("god", "dog"));时,您未检查组合"god" and "dog",但检查每个元素goddogSet<Set<String>>中存在catgroups contains `god` -> no groups contains `dog` -> no return false 不是,在你的集合中,你只有一个元素groups.stream().anyMatch(a -> a.equals(set2))// or groups.stream().anyMatch(set2::equals) 是分开的。它就像:

groups.stream().anyMatch(a -> a.containsAll(set2))

要解决您的问题,您可以使用等于:

a

4

答案 2 :(得分:0)

试试这个。

static String sort(String s) {
    int[] sortedCP = s.codePoints().sorted().toArray();
    return new String(sortedCP, 0, sortedCP.length);
}

public static Set<Set<String>> group(Set<String> words) {
    Map<String, Set<String>> map = new HashMap<>();
    for (String word : words)
        map.computeIfAbsent(sort(word), k -> new HashSet<>()).add(word);
    return new HashSet<>(map.values());
}

Set<String> words = new HashSet<>(Arrays.asList("cat", "dog", "god"));
System.out.println(group(words));

结果:

[[cat], [god, dog]]

中间变量map

{act=[cat], dgo=[god, dog]}