2016-03-21 179 views
-3

我有一个与ping相关的Arraylist,这些是链接到名称的日期,我想删除名称的所有重复项并保留名称的最近日期。ArrayList重复删除

代码

private ArrayList <String> deleteDuplicates() { 
    ArrayList <Ping> tempPings = new ArrayList <Ping>(); 
    tempPings.addAll(jaws.pastMonth()); 
    for (int i = 0; i < tempPings.size(); i++) { 
    Ping tempPing = tempPings.get(i); 
    for (int j = i + 1; j < tempPings.size() - 1; j++) { 
     Ping tempPing2 = tempPings.get(j); 
     if (tempPing.getName().equals(tempPing2.getName())) { 
     if (changePingToDate(tempPing2).before(changePingToDate(tempPing))) { 
      tempPings.remove(j); 
     } 
     } 
    } 
    } 
    return pingToNames(tempPings); 
} 

changePingToDate()是将日期字符串转换成公历的方法。

当我使用这段代码时,它删除了大部分重复项,但是每次循环中仍有一些剩余项。我也尝试过,没有比较日期和仍然是同样的问题。谁能帮忙?

感谢您的帮助!

+0

@aribeiro嗨,我已经检查了答案,它并没有帮助我的问题,我的.equals似乎工作正常,名称是完全相同的,例如“玛丽李”多次,它似乎选择选择删除哪些。 –

+1

您正在调用'.remove()',它可以修改列表的大小和**您正在查看的索引**。你正在跳过价值。 –

+2

使用迭代器。为了这个原因,我不想在这里添加另一个答案。 SO和Google都有大量的资源可用。 –

回答

0

不要在列表内部循环时从列表中删除元素。因此,将要删除的所有项目添加到另一个列表中,最后从tempPings中删除所有项目。

private ArrayList <String> deleteDuplicates() { 
    ArrayList <Ping> tempPings = new ArrayList <Ping>(); 
    tempPings.addAll(jaws.pastMonth()); 

    ArrayList <Ping> pingsToRemove = new ArrayList <Ping>(); 
    for (int i = 0; i < tempPings.size(); i++) { 
    Ping tempPing = tempPings.get(i); 
    for (int j = i + 1; j < tempPings.size() - 1; j++) { 
     Ping tempPing2 = tempPings.get(j); 
     if (tempPing.getName().equals(tempPing2.getName())) { 
     if (changePingToDate(tempPing2).before(changePingToDate(tempPing))) { 

      pingsToRemove.add(tempPings.get(j)); 

     } 
     } 
    } 
    } 

    tempPings.removeAll(pingsToRemove); 
    return pingToNames(tempPings); 
} 
+0

你可以使用'Iterator.remove' –

+0

我已经试过这种方式,它结束了,我的400个奇数大小的数组中,9060个元素删除,不知道为什么发生这种情况,如果我要使用迭代器会需要使用两个?我从来没有见过并用迭代器迭代迭代器来迭代已经检查过的元素(对于j = i + 1的情况),这可能吗?谢谢。 –

+0

尝试在'pingsToRemove.add(tempPings.get(j));'前检查'tempPings.get(j)'是否已经添加了if语句。像'if(!pingsToRemove.contains(tempPings.get(j)))'。 – rdonuk

-1

你并不需要“-1”的位置:

for (int j = i + 1; j < tempPings.size() - 1; j++) { 

这将导致你从来没有在列表中的最后一项进行比较。 j < tempPings.size()足以防止超过数组的末尾。

0

由于您在理解为什么remove()操作正在导致问题的问题。我会尽力解释。

这是一个概括性的解释,给出你的代码中的问题的想法。

我有一桶10件东西。在每次迭代中,我都会检查以确保我正在检查,直到bucket.size()。如果我删除i的项目,则i+1的项目将取代它。删除过程确保bucket.size()现在等于9,而不是10.循环将我的i增加1。跳过i+1处的元素,现在处于i

+0

非常感谢你,非常感谢你! –

+0

@ B.KLewis [This post](http://stackoverflow.com/questions/12196762/delete-duplicates-in-java-arraylist)和[this post](http://www.rgagnon.com/javadetails/ java-remove-duplicates-in-a-list.html)展示了使用迭代器完成这件事情的很好的方法。 –

1
ArrayList<String> values = new ArrayLiist<>(Arrays.asList(
     "apple", 
     "banana", 
     "grape", 
     "banana", 
     "apple", 
     "banana", 
     "apple", 
     "grape" 
)); 

使用Java 8?

values = values.stream().distinct().collect(Collectors.toCollection(ArrayList::new)); 

只有Java 7?

values = new ArrayList<>(new LinkedHashSet<>(values)); 

输出两个是

[apple, banana, grape] 

然后,只需在列表上正常人一样做你的约会操作循环。

+0

这将是非常有用的,不幸的是,我们仍然需要比较日期,并为每个ping命名留下独特的名称,也是最接近的时间。不过谢谢,未来可以看到这非常方便! –

+0

删除重复项后,只需遍历列表即可。 –

+0

@ cricket_007流与LinkedHashSet的第二种方式有什么优势? –