繁体   English   中英

在不包含哈希值的ArrayList中删除重复项

[英]Removing duplicates in ArrayList w/o Hashset

我可以删除大多数重复项,除了彼此相邻的重复项。 我不知道我在做什么错。 现在,我嵌套了for循环,将int与ArrayList中的其余部分进行比较。 除了我设置或递增的方式之外,我跳过了重复的内容,而在我再次开始第一个for循环的地方旁边。 我发现删除索引j后重置i = 0非常有用。 如果它们紧挨着,它仍然不会删除重复项。

for(int i=0;i<original.size();i++){
    for(int j=i+1;j<original.size();j++){
        if(original.get(i)==original.get(j)){
            original.remove(j);   
        }
    }
}

编辑:我找到了解决方案,当我将第二个for循环更改为while循环,然后每次递增,但是当我发现重复项时,我从j中删除了1。 这样,我将重新开始。

谢谢你们。

笔记:

1)如果您从Arraylist中删除 ,大小将减小 ,索引将减小

例如:

如果原始arraylist是:{a,b,c,d},并且索引i = 2(c); 如果您删除了original(2)(=====从原件中删除c),则索引将是i ++引用它不存在的original(3)!

2)什么是您的对象类型? 如果它们是字符串,那么您将使用.equal()

使用equals代替== 更改if语句,例如:

 original.get(i).equals(original.get(j))

您应该使用迭代器删除列表中的元素,而不是使用列表本身。

使用obj.equals(obj other)函数比较字符串或对象,而不是==运算符。

  for(int i=0;i<original.size();i++){
  for(int j=i+1;j<original.size();j++){
      if(original.get(i).equals(original.get(j))){
          original.remove(j);
      }
  }
  }

如果要基于该对象的某个值删除该对象,则需要重写bean类的equals方法。 请看一下Java中的equals方法。 如果您重写bean类,则不需要两个for循环来删除重复项。 将对象添加到数组列表时,可以避免重复。

不知道为什么不希望使用HashSet ,而不管是否需要使用.equals()而不是== ,因为您正在查看的是值,而不是引用。 另外,如果您使用循环并从列表中删除一个元素,则您不想增加j因为这会跳过一个元素,显然您不想这样做。

每当您按列表上的索引循环并删除时, 都必须循环“向后” 让j向后循环。 否则,您最终将跳过条目。 正如@BinaryMan也指出的那样。

例如(请注意,也使用equals()代替==)

for(int i=original.size()-1;i>=0;i--){
    for(int j=original.size()-1;j>i;j--){
        if(original.get(i).equals(original.get(j))){
            original.remove(j);   
        }
    }
}

假设列表看起来像这样: [a,a,a,b,c,a]

这是迭代的样子(迭代完成后查看,删除或不删除):

i=0, size = 6 , j=1, arr[i] = a, arr[j] = a, view: [a,a,b,c,a]; (arr[i]==arr[j], will delete)
i=0, size = 5,  j=2, arr[i] = a, arr[j] = b, view: [a,a,b,c,a]; (arr[i]!=arr[j])
i=0, size = 5,  j=3, arr[i] = a, arr[j] = c, view: [a,a,b,c,a]; (arr[i]!=arr[j])
i=0, size = 5,  j=4, arr[i] = a, arr[j] = a, view: [a,a,b,c];   (arr[i]==arr[j], will delete)
i=1, size = 4,  j=2, arr[i] = a, arr[j] = b, view: [a,a,b,c];   (arr[i]!=arr[j])
i=1, size = 4,  j=3, arr[i] = a, arr[j] = c, view: [a,a,b,c];   (arr[i]!=arr[j])
i=2, size = 4,  j=3, arr[i] = b, arr[j] = c, view: [a,a,b,c];   (arr[i]!=arr[j])
i=3, size = 4, .......

邻居不会删除,因为j = i + 1,它将永远不会有机会互相检查,因为一旦删除了元素,数组就会向下移动一个索引,因此在下一次迭代中,您要检查的项实际上是由于j=i+1跳过

如果数组元素为整数,则首先对数组进行排序会更有效

    Collections.sort(list);
    Iterator<Integer> i = list.iterator();
    int prev = i.next();
    while (i.hasNext()) {
        int next = i.next();
        if (next == prev) {
            i.remove();
        } else {
            prev = next;
        }
    }

请注意,Integers的original.get(i)==original.get(j)不会比较值,即new Integer(1000) == new Integer(1000)生成false

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

public class RemDupFromList {

    public static void main(String[] args)
    {
        List li = new ArrayList();

              li.add("one");
              li.add("two");
              li.add("three");
              li.add("one");//Duplicate
              li.add("one");//Duplicate

             // We have facility to pass a List into Set constructor and vice verse to cast      

                List li2 = new ArrayList(new HashSet(li)); //no order

             // List li2 = new ArrayList(new LinkedHashSet(li)); //If you need to preserve the order use 'LinkedHashSet'

             Iterator it= li2.iterator();
             while(it.hasNext())
             {
                 System.out.println(it.next());
             }

    }
}
ArrayList<String> wordDulicate = new ArrayList<String>();
ArrayList<String> tempList= new ArrayList<String>();

    wordDulicate.add("7");
    wordDulicate.add("7");
    wordDulicate.add("7");

    for (String dupWord : wordDulicate)
    {
      if (!tempList.contains(dupWord)) 
      {
        System.out.println(dupWord);
        tempList.add(dupWord);
      }
    }

templist您将没有重复的条目。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM