2013-04-07 57 views
1

只是一个免责声明:我第二次重复了我的java mod,所以我的问题可能会有点简单,希望我听起来不太愚蠢。去除arraylist中的重复项

写方法removeDuplicates是作为一个参数排序的 ArrayList的字符串,并从列表中排除任何重复。 例如,假设名为list的变量包含以下值 :{"be", "be", "is", "not", "or", "question", "that", "the", "to", "to"}调用removeDuplicates(list);列表 应存储以下值:{"be", "is", "not", "or", "question", "that", "the", "to"}

因为值将被排序,所有重复项将被组合在一起。

我尝试这个:

public static void removeDuplicates(ArrayList <String>a){ 
    for(int i=0;i<a.size();i++){ 
     String word=a.get(i); 
     String word2=a.get(i+1); 

     if(word.equals(word2)){ 
      a.remove(word); 

     } 
     else{ 
      System.out.print(word); 

     } 
    } 
} 

的问题是,当我把它叫做:

["duplicate", "duplicate", "duplicate", "duplicate", "duplicate"] 

返回indexoutofbound。我知道这与i=i-1有关,并参考remove方法。尝试插入它在这里,但它不起作用。但是我很困惑,因为这与我的代码一起工作。当我打电话给:

["be", "be", "is", "not", "or", "question", "that", "the", "to", "to"] 

它的工作原理。

+0

这是否帮助? http://stackoverflow.com/questions/13429119/get-unique-values-from-arraylist-in-java – Aiias 2013-04-07 05:54:03

+1

为什么不能使用一个相同的集合。这不会让您在第一时间输入重复值。 – 2013-04-07 05:54:04

+0

你好啊,它并没有真正的帮助。我不喜欢设置的方法。因为它没有被教导,所以会更喜欢与设置无关的东西 – user2179615 2013-04-07 05:56:33

回答

0

您有两个错误: 第一个错误是您尝试访问不存在的对象。 当i = a.size(),String word2=a.get(i+1)哪个不存在!

另一个错误是在迭代列表时删除元素。

您应该改用iterator

解决它,而无需使用迭代的方法是:使用 :

for(int i=0;i<a.size() - 1;i++){ 

和:

if(word.equals(word2)){ 
    a.remove(word); 
    i--; 
} 
+0

嗯,它不适用于[“重复” ,“复制”,“复制”,“复制”,“复制”] – user2179615 2013-04-07 06:04:56

+0

这是一个新错误还是与以前相同? – BobTheBuilder 2013-04-07 06:15:07

+0

当我调用[“重复”,“重复”,“重复”,“重复”,“重复”]时出现新错误,它返回3 [重复,重复,重复] – user2179615 2013-04-07 06:17:11

1

你的实现有缺陷。

String word=a.get(i); 
String word2=a.get(i+1); 

将在u到达最后一个元素时出现界限。

其次,你正在删除元素,因为你直接从arraylist迭代,这是行不通的。您改为迭代器。

0

您可以使用设定的附加给它

+0

这可能会删除太多元素,每个约束。出现的元素(例如[A,B,B,A])将被视为无效输入,不应将其重复删除。 – Makoto 2013-04-07 06:56:12

0

您的循环时,应i < a.size() - 1这将删除重复的元素。

让您的大小为4.当您迭代i = 3时,您将获得word2的indexoutofbound,尝试访问索引4的值,该值实际上是从0到第3个索引。

0

void unique (ArrayList<String> a) 
{ 
    if(a.length() == 0) 
     return; 

    int result = 0; 
    int first = 0; 
    int last = a.length(); 
    while (++first<last) 
    { 
     String r = a.get(result); 
     String cur = a.get(first); 
     if(!cur.euqals(r)) 
      a.set(++result,cur); 
    } 
    a.removeRange(++result,last); 
} 

我希望这个代码块可以帮助你。

0

好的,所以我打算在你身上抛出语法和一些列表迭代概念。振作起来,让你的Java 7 API方便。


解决这个问题如下,在普通的步骤:

  • 迭代通过列表。
  • 检查列表中的相邻元素。
    • 如果它们匹配,请将其删除。
    • 否则,让它一个人。
  • 返回最终的非重复列表。

假设下进行:

  • 具有重复元件是不相邻的其他重复元素被假定表现出非设置行为的列表 - 也就是说,如果我有输入[A, B,B,A]我期望[A,BA]作为输出。这就是我为什么不是推荐使用Set这个。

有谨慎的上只使用remove()一个字 - if this list is accessed concurrently, then you will run into ConcurrentModificationException!优选和稍微干净的方法是使用IteratorListIterator接口来代替。

我们有四个案件遇到之前我们反复:

  • 空(无元素) - 应该被禁止,因为我们是[几乎]保证我们不会有一个空列表
  • 单(只有一个元素,没有重复)
  • 二进制(两个元件,一个威力是重复)
  • 聚(ñ> 2种元素)

有一个边缘情况我们必须考虑 - 超过三个重复元素。这意味着,当我们迭代时,我们必须查看之前的下一个元素,以确定是否应该删除它。

采取,例如,本实施例中输入:

[A, A, A, B, C, D] 

如果我们在幼稚方法迭代(看着i + 1的同时推进),然后我们将完全跳过的元件。不看左,右上面的结果将是:

[A, A, B, C, D] 

为了解决这个问题,我们使用ListIterator,它支持先前的操作。通过这个与天真的前一种方法

一个运行会产生更坏的结果比以前 - 因为我们已经重置了当前光标的位置,我们已经检查它,我们将前进到下一个节点将被认为是错误的重复! (讽刺的是,你不会摆脱第一对重复。)

要解决,我们重置光标到原来的位置,我们在我们向左看。

下面是解决方案。它适用于任何规模的清单,关于我们上面定义的约束和预期行为。

public List<String> removeDuplicates(final ArrayList<String> dupeList) { 
    if(dupeList.size() == 0) { 
     throw new IllegalArgumentException("Zero-length list == evil"); 
    } 
    ListIterator<String> li = dupeList.listIterator(); 
    String w1; 
    String w2; 
    if(dupeList.size() == 1) { 
     return dupeList; 
    } else if(dupeList.size() == 2) { 
     w1 = li.next(); 
     w2 = li.next(); 
     if(w1.equals(w2)) { 
      li.remove(); 
     } 
    } else { 
     while(li.hasNext()) { 
      if(li.hasPrevious()) { 
       w1 = li.previous(); 
       li.next(); // explained a bit above 
      } else { 
       w1 = li.next(); 
      } 
      if(li.hasNext()) { 
       w2 = li.next(); 
       if(w1.equals(w2)) { 
        li.remove(); 
       } 
      } 
     } 
    } 
    return dupeList; 
} 
1

我会建议你改变返回类型ArrayList<String>和使用Set消除重复。具体方法如下:

public static ArrayList<String> removeDuplicates(ArrayList <String>a){ 
    return new ArrayList<String>(new HashSet<String>(a)); 
} 

或者,在for循环a.size()-1当前的代码更改上限:

for(int i=0;i<a.size()-1;i++) // this should prevent arrayindexoutofbound exception.