簡體   English   中英

重復元素未從ArrayList中刪除

[英]Duplicates elements not removed from ArrayList

我正在嘗試使用以下代碼向數組添加唯一元素。 我使用了Ignorecase,但仍然出現重復。

    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;

    public class RemoveDuplicatesIgnoreCase {

    public static void main(String args[]) {

        // String Array with duplicates Colors
        String[] colorArray={"Black","BLACK","black","Cobalt","COBALT","cobalt","IVORY","Ivory","ivory","White","WHITE","white"};
        List<String> uniqueColorList=new ArrayList<String>();
        for (String color : colorArray) {
            if(!uniqueColorList.contains(color)&& !uniqueColorList.contains(color.toLowerCase())&& !uniqueColorList.contains(color.toUpperCase()))
            {
                uniqueColorList.add(color);
            }
        }
        Iterator<String> itr=uniqueColorList.iterator();
        while(itr.hasNext())
        {
            System.out.println(itr.next());
        }

    }

}

輸出:

Black
BLACK
Cobalt
COBALT
IVORY
White
WHITE

我想避免添加區分大小寫和不區分大小寫的重復項。

我將使用SET而不是ArrayList並以小寫形式添加字符串。 該Set不允許重復的元素。

Set<String> uniqueColorList = new HashSet<String>();
for (String color : colorArray) {
    uniqueColorList.add(color.toLowerCase());
}

您必須降低兩個值的大小寫以找到匹配項

我將使用一Set顏色的小寫版本來跟蹤唯一性:

public static void main(String args[]) {

    String[] colorArray={"Black","BLACK","black","Cobalt","COBALT","cobalt","IVORY","Ivory","ivory","White","WHITE","white"};

    List<String> colors = new ArrayList<String>();
    Set<String> uniqueColors = new HashSet<String>();
    for (String color : colorArray) {
        if (set.add(color.toLowerCase()) {
            uniqueColors.add(color);
        }
    }
    // colors now contains case-insensitive unique names 
}

這段代碼利用了Set的兩件事:

  1. 集合僅允許唯一值,因此通過放入字符串的小寫副本,我們可以區分大小寫不敏感的部分
  2. 如果操作更改了集合,則add()方法將返回true ,這僅在要添加的值是該集合的新值時才會發生。使用此返回值避免了必須使用contains() -只需嘗試添加該值,您就可以會找出它是否唯一。

我認為正確的方法是將顏色封裝在對象中。 這僅是最小的開銷,並且使您的代碼更具可讀性:

public class ColorString {
    public final String str;

    public ColorString(String str) {
      this.str = str;
    }

    public boolean equals(Object obj) {
        if (obj == null) return false;
        if (obj == this) return true;
        if (!(obj instanceof ColorString )) return false;

        ColorString col = (ColorString) obj;

        if (this.str == null) return (col.str == null);

        return this.str.equalsIgnoreCase(col.str);
    }

    public int hashCode() { // Always override hashCode AND equals
        return str.toLowerCase().hashCode();
    }

}

如果這樣做,則可以使用所有標准方法,可以使用Set,ArrayList.contains等。 這種解決方案更合理,因為它代表了這種想法:您沒有字符串,但是有一個“顏色”,並且有特殊的規則,當應將兩個“顏色”視為相等或不相等時。

而且,如果您想擴展您的解決方案,例如,通過允許將具有相似名稱的多種顏色視為相同的“顏色”,則只需更改一種方法,一切仍然可以進行!

您的問題是,您只涵蓋所有小寫和所有大寫的Strings ,而不涵蓋任何其他大小寫混合(例如,您也有大寫的String)。

簡而言之,您可以擴展ArrayList並覆蓋contains以對每個String使用不區分大小寫比較,如該線程中所示

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class RemoveDuplicatesIgnoreCase {
    public static void main(String args[]) {

        // String Array with duplicates Colors
        String[] colorArray={"Black","BLACK","black","Cobalt","COBALT","cobalt","IVORY","Ivory","ivory","White","WHITE","white"};
        List<String> uniqueColorList=new IgnoreCaseStringList<String>();
        for (String color : colorArray) {
            if(!uniqueColorList.contains(color))
            {
                uniqueColorList.add(color);
            }
        }
        Iterator<String> itr=uniqueColorList.iterator();
        while(itr.hasNext())
        {
            System.out.println(itr.next());
        }

    }

}

public class IgnoreCaseStringList extends ArrayList<String> {
    @Override
    public boolean contains(Object o) {
        String paramStr = (String)o;
        for (String s : this) {
            if (paramStr.equalsIgnoreCase(s)) return true;
        }
        return false;
    }
}

這是行不通的,因為您首先要添加既不大寫也不小寫的Black。

您可以決定添加大寫或小寫字符串,並且更好的是,如果順序無關緊要,請使用TreeSet。 TreeSet將使其按字母順序排序。

I want to avoid adding case sensitive & case insensitive duplicates.

在比較String與比較值時,必須將所有String都轉換為小寫或大寫。

您可以使用equalsIgnoreCase()

但是更好,更簡單的方法是使用Set因為它僅保留唯一的值。

Set<String> uniqueVal = new HashSet<String>();
for (String color : colorArray) {
    uniqueVal.add(color.toLowerCase());
}

您可以再次將Set轉換為List

List<String> uniqueList=new ArrayList<>(uniqueVal); 
// Now list contains unique values only 

我會這樣:

List<String> uniqueColorList = new ArrayList<String>();
Set<String> processedColors = new HashSet<String>();

for (String color : colorArray) {
    String lowerCase = color.toLowerCase();
    if (processedColors.add(lowerCase)) {
        uniqueColorList.add(color);
    }
}

但這取決於輸出結果。 如果你只是想在輸出列表中大寫或小寫顏色名稱uniqueColorList和順序應該保持不變,如inputColorArray比你應該使用LinkedHashSet

String[] colorArray = { "Black", "BLACK", "black", "Cobalt", "COBALT",
            "cobalt", "IVORY", "Ivory", "ivory", "White", "WHITE", "white" };
Set<String> uniqueColors = new LinkedHashSet<String>();

for (String color : colorArray) {
    uniqueColors.add(color.toLowerCase());
}

原因是您喜歡所有小寫字母

當您檢查BLACK時,列表中有Black,但Black!= black。

小寫字符串的第一個字符為大寫。

首先這部分:

uniqueColorList.contains(color)

將不起作用,這是因為當對字符串執行.equals時,大小寫不同。 那么您的下一個問題是小寫和大寫都不起作用,因為第一個如果混合使用。 歸結為WHITE和White在技術上是獨一無二的事實。 根據鄒鄒的建議,最簡單的選擇是只使用一個固定的案例。 否則,您需要執行Domi所說的並實現自己的contains方法來進行不區分大小寫的檢查

Set<String> duplicateDection = new HashSet<>()
if (duplicateDection.add(color.toLowerCase())) {
  uniqueColorList.add(color);
}

如果從列表中刪除項目,則還需要從重復檢測中刪除它們:

uniqueColorList.remove(color);
duplicateDetection.remove(color.toLowerCase());

您僅檢查要構建的列表是否已包含要添加的元素的“相同大小寫”“大寫”“小寫”變體,因此如果列表已包含具有不同大小寫組合的字符串,則搜索不是窮舉,那么它將通過條件並添加顏色。

嘗試這個..

public static void main(String[] a) {
    String[] colorArray = {"Black", "BLACK", "black", "Cobalt", "COBALT", "cobalt", "IVORY", "Ivory", "ivory", "White", "WHITE", "white"};
    List<String> uniqueColorList = new ArrayList<String>();

    for (int i = 0; i < colorArray.length; i++) {
        for (int j = i+1; j < colorArray.length; j++) {
            if (!colorArray[i].equals("")) {
                if (colorArray[i].equalsIgnoreCase(colorArray[j])) {
                    colorArray[j] = "";
                }
            }
        }
    }
    System.out.println(Arrays.toString(colorArray));;
    for (String color : colorArray) {
        if (!color.equals("")) {
            uniqueColorList.add(color);
        }
    }
    Iterator<String> itr = uniqueColorList.iterator();
    while (itr.hasNext()) {
        System.out.println(itr.next());
    }
}
public static void main(String args[]) {

    String[] colorArray={"Black","BLACK","black","Cobalt","COBALT","cobalt","IVORY","Ivory","ivory","White","WHITE","white"};
    Set<String> uniqueColorList = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
    for (String color : colorArray) {
            uniqueColorList.add(color);
    }
    Iterator<String> itr=uniqueColorList.iterator();
    while(itr.hasNext())
    {
        System.out.println(itr.next());
    }

}

這將解決您的問題

輸出:

Black
Cobalt
IVORY
White

暫無
暫無

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

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