在Java中比较两个集合以获取一个集合而不是另一个集合中的元素的最快方法是什么

时间:2017-03-22 13:44:52

标签: java performance hashset

我在这里有两个Hashset 用户 docbaseuser

我的代码:

Iterator iterator = user.iterator();

        while (iterator.hasNext())
        {
            String isid = (String)iterator.next();
            flag = getCount(isid, Docbaseuser);
            if(flag == 0)
            {
                count++;
                System.out.println("Unique user found!");
            }

        }



private int getCount(String isid, Set<String> docbaseuser) 
    {
        // TODO Auto-generated method stub

        int flag = 0;
        System.out.println("execution reached getcount");
        Iterator iterator = docbaseuser.iterator();
        while(iterator.hasNext())
        {
            String id = (String) iterator.next();
            if(isid.equalsIgnoreCase(id))
            {
                System.out.println("MATCH !!!");
                flag++;
                break;
            }
        }
        return flag;
    }

有没有更好的方法来比较hashset用户和hashset docbaseuser并从docbaseuser中不存在的用户哈希集中获取元素? 提前谢谢!

3 个答案:

答案 0 :(得分:0)

boolean flag=false; 
for(String files:user){
    for(String dbu:docbaseuser){
        if(files.equalsIgnoreCase(dbu)){
            flag=true;
        }
    }
    if(flag){
        //user already exists
        flag=false;
    }

答案 1 :(得分:0)

我想你可以这样做:

public Set<String> fetch (Set<String> here, Set<String> notHere) {
    return here.stream()
            .filter(h -> !isIn(h, notHere))
            .collect(Collectors.toCollection(HashSet::new));
}

private boolean isIn (String s, Set<String> set) {
    for (String str : set) {
        if (str.equalsIgnoreCase(s)) return true;
    }
    return false;
}

编辑:如果您不需要equalsIgnoreCase,那么您可以这样做:

public Set<String> fetch (Set<String> here, Set<String> notHere) {
    return here.stream()
            .filter(h -> !notHere.contains(h))
            .collect(Collectors.toCollection(HashSet::new));
}

答案 2 :(得分:0)

如果您需要userdocbaseuser中不存在的所有字符串的集合,就好像您使用String.equalsIgnoreCase()逐个比较但希望 O(1) 查找HashSet O(log n) TreeSet复杂度中元素的复杂性,请注意不要简单地将所有字符串转换为大写或小写使用String.toUpperCase()或类似的。例如。一个人可能会想要使用new TreeSet<>(String.CASE_INSENSITIVE_ORDER)

这是一个解决方案,其行为与使用String.equalsIgnoreCase() O(1)复杂度的字符串进行比较,其初始成本为HashSet,用作索引。但根据上下文,这可以在其他地方维护,并与docuserbase内容的更改保持同步。

@FunctionalInterface
private static interface CharUnaryOperator {
    char applyAsChar(char operand);
}

private static String mapCharacters(String s, CharUnaryOperator mapper) {
    char[] chars = s.toCharArray();
    for (int i = 0; i < chars.length; i++)
        chars[i] = mapper.applyAsChar(chars[i]);
    return String.valueOf(chars);
}

private static Set<String> stringsNotPresentInOtherSetIgnoreCase(Set<String> set, Set<String> otherSet) {
    Set<String> index = otherSet.stream()
            .flatMap(s -> Stream.of(
                    mapCharacters(s, Character::toUpperCase),
                    mapCharacters(s, Character::toLowerCase)
                    ))
            .collect(Collectors.toCollection(HashSet::new));
    return set.stream()
            .filter(s -> !index.contains(mapCharacters(s, Character::toUpperCase)))
            .filter(s -> !index.contains(mapCharacters(s, Character::toLowerCase)))
            .collect(Collectors.toCollection(HashSet::new));
}

private static void test() {
    Set<String> user = Stream.of("max", "John", "PETERSSON", "Tommy", "Strauß").collect(Collectors.toSet());
    Set<String> docbaseuser = Stream.of("Max", "Petersson", "Steve", "Brad", "Strauss").collect(Collectors.toSet());

    Set<String> usersNotInDocbaseuser = stringsNotPresentInOtherSetIgnoreCase(user, docbaseuser);

    if (!usersNotInDocbaseuser.equals(Stream.of("John", "Tommy", "Strauß").collect(Collectors.toSet()))) {
        System.out.println("Wrong result");
    }
}

将该代码粘贴到某个类并调用test()以确保stringsNotPresentInOtherSetIgnoreCase()方法正常工作。在使用Strauß进行转换之前,请特别注意被视为相等的字符串StraussString.toUpperCase()

System.out.println("Strauß".toLowerCase().equals("strauss".toLowerCase()));
System.out.println("Strauß".toUpperCase().equals("strauss".toUpperCase()));
System.out.println("Strauß".equalsIgnoreCase("strauss"));

结果:

false
true
false