[英]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)在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()
方法正確運行。 請特別注意在以下情況下使用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.