簡體   English   中英

在Java中比較兩組以獲取一組而不是另一組中的元素的最快方法是什么

[英]What is the fastest way to compare two sets in Java to get the elements that are in one set and not the other

我在這里有兩個Hashsets 用戶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;
    }

有什么更好的方法可以將哈希集用戶與哈希集docbaseuser進行比較,並從docbaseuser中不存在的用戶哈希集中獲取元素? 先感謝您!

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

我認為您可以這樣實現:

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));
}

如果您需要一組user中所有不存在於docbaseuser字符串,就好像您使用String.equalsIgnoreCase()進行了一個一一個的比較,但是想要O(1)HashSetO(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()方法正確運行。 請特別注意在以下情況下使用String.toUpperCase()進行轉換時被視為相等的字符串StraußStrauss

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM