2016-03-21 33 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個の要素を削除してしまいました。イテレータは2つの使用を必要としますか?すでにチェックされた要素(j = i + 1の場合)を反復するイテレータを使ってこれを見たことはありませんでしたが、これは可能ですか?ありがとう。 –

+0

'pingsToRemove.add(tempPings.get(j));'の前にif文を追加して、 'tempPings.get(j)'がすでに追加されているかどうかを確認してください。 'if(!pingsToRemove.contains(tempPings.get(j)))'のように。 – rdonuk

-1

あなたは必要としない「-1」をここに:

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

リスト内の最後の項目と比較しないように引き起こすこと。 j < tempPings.size()は、配列の最後を通過するのを防ぐのに十分です。

0

あなたは、あなたがやっているremove() opが問題を引き起こしている理由を理解する問題が発生しているので。私は説明しようとします。

これは一般的な説明で、コード内の問題についての考え方を示しています。

私には10種類のバケツがあります。すべての反復で、私はbucket.size()までチェックしていることを確認します。 iでアイテムを削除すると、i+1のアイテムがその場所に移動します。削除処理では、bucket.size()が10ではなく9になりました。ループは私の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での2番目の方法によるストリームの利点は何ですか? –