复制未从ArrayList中删除的元素

时间:2013-12-05 12:24:40

标签: java 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

我想避免添加区分大小写的&amp;不区分大小写的重复项。

14 个答案:

答案 0 :(得分:4)

我会使用SET而不是ArrayList并以小写形式添加字符串。 Set不允许重复元素。

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

答案 1 :(得分:2)

你必须降低两个值,才能找到匹配

答案 2 :(得分:1)

我会使用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,只有当添加的值对集合是新的时才会发生,使用此返回值可避免必须使用{{1} - 只是尝试添加值,你会发现它是否是唯一的。

答案 3 :(得分:1)

我认为执行此操作的正确方法是将Color封装在对象中。 它只是最小的开销,使你的代码更具可读性:

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等。这个解决方案更明智,因为它代表了这个想法:你没有字符串,但你有一个“颜色”,你有特殊的规则,当两个“颜色”应该被认为是相同或不同。

如果您想扩展您的解决方案,例如通过允许将具有相似名称的多种颜色视为相同的“颜色”,您只需更改一种方法,一切仍然有效!

答案 4 :(得分:0)

您的问题是,您只覆盖所有小写和所有大写Strings,而不是任何其他情况(例如,您还有大写字符串)。

简而言之,您可以扩展ArrayList并覆盖contains以对每个String使用忽略案例比较,如建议的in this thread

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

答案 5 :(得分:0)

它不起作用,因为你首先添加既不是大写也不是小写的黑色。

您可以决定添加大写或小写字符串,更好的是,如果排序对您无关紧要,请使用TreeSet。 TreeSet将按字母顺序排序。

答案 6 :(得分:0)

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

在比较字符串时,您必须将所有字符串设置为小写或大写字母与比较值相同。

您可以使用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 

答案 7 :(得分:0)

我会这样做:

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

答案 8 :(得分:0)

原因是你所有的小写

都是checikng

当您检查黑色时,列表中有黑色,但黑色!=黑色。

小写字符串的第一个字符是大写。

答案 9 :(得分:0)

首先关闭这一部分:

uniqueColorList.contains(color)

不起作用,这是因为当它在字符串上执行.equals时,情况就不同了。那你的下一个问题是大小写不起作用,因为第一个如果混合了。它归结为白色和白色在技术上是独一无二的。根据ZouZou的建议,最简单的选择是使用单个案例。否则你需要做Domi所说的并实现你自己的contains方法来做一个不区分大小写的检查

答案 10 :(得分:0)

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

如果从列表中删除项目,您还需要将其从重复检测中删除:

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

答案 11 :(得分:0)

您只检查正在构建的列表是否已包含要添加的元素的“相同大小写”“大写”“小写”变体,因此如果列表已包含具有不同大小写组合的字符串,则搜索并非详尽无遗然后它通过条件并添加颜色。

答案 12 :(得分:0)

试试这个..

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

答案 13 :(得分:0)

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