[英]Removing duplicates in an arraylist
只是免责声明:我第二次重复了我的Java mod,所以我的问题可能会有点简单,希望我听起来不会太愚蠢。
编写方法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
。 我了解到与remove
方法有关,它与i=i-1
有关。 试图在这里和那里插入它,但是不起作用。 但是我很困惑,因为这适用于我的代码。 当我用以下方式调用它时:
["be", "be", "is", "not", "or", "question", "that", "the", "to", "to"]
有用。
您的实现存在缺陷。
String word=a.get(i);
String word2=a.get(i+1);
当您到达最后一个元素时,将超出范围。
其次,当您直接从arraylist进行迭代时,您将删除元素,这将不起作用。 您改为迭代器。
我建议您将返回类型更改为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.
您有两个错误:第一个错误是您尝试访问不存在的对象。 当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--;
}
您可以使用Set将添加到其中的元素删除重复的元素
您的for循环应为i < a.size() - 1
。
假设大小为4。当对i = 3
进行迭代时,将获得word2的indexoutofbound,尝试访问索引4的值,该值实际上是从0到3rd的索引。
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);
}
我希望此代码块可以为您提供帮助。
好吧,所以我将向您介绍语法和相当多的列表迭代概念。 振作起来,并准备好使用Java 7 API。
通过简单的步骤可以解决此问题:
假设:
Set
的原因。 仅使用remove()
时要特别小心- 如果同时访问此列表,则将遇到ConcurrentModificationException
! 一种首选且稍微清洁一点的方法是改为使用Iterator
或ListIterator
接口。
在迭代之前,我们有四个案例:
我们不得不考虑一个极端的情况-超过三个重复的元素。 这意味着,在进行迭代时,我们必须查看上一个和下一个元素,以确定是否应删除它。
以这个示例输入为例:
[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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.