1

私はJavaにかなり慣れていないので、次の問題を解決しようとして失敗しました。

指定されたリストから重複を削除する Java メソッドを作成します。

仮定:

  1. メソッドは List 型を受け入れます
  2. リターンタイプはvoid
  3. 重複は次を使用して決定されますequals()

主要:

  1. リストのインスタントを作成し、重複する文字列値でロードします
  2. を呼び出しremoveDuplicates()、このリストを渡します
  3. 変更されたリストをコンソールに出力します。

リストを新しい HashSet に渡してコピーすることで、問題を解決できます。しかし、問題は次のとおりです。

  1. 質問は私にそれを解決するように求めていますequals()...
  2. 戻り値の型が の場合void、どのように出力できmainますか?

import java.util.*; 公開クラス 質問1 {

    public static void main(String[] args) {
String[] words = {"good","better", "best", "best", "first" , "last", "last", "last", "good"};  
        List<String> list = new ArrayList<String>();  
        for (String s : words) {  
            list.add(s);  
        }  
        removeDuplicates(list);
    }
    static void removeDuplicates(List<String> array){
        HashSet<String> hs = new HashSet<>();
        hs.addAll(array);
        array.clear();
        array.addAll(hs);
        for (String x : array){ 
            System.out.println(x);
        }
    }
}

編集:まあ、これは機能しますが、ご覧のとおり、equals() を使用しておらず、main からではなく静的メソッドから出力しています。また、 String[] を使用するよりも速く List を作成する方法はありますか?

4

4 に答える 4

3

java.util.HashSetObject.equals(Object)の実装で使用しSet.add(Object)て、挿入される要素が一意であることを判断します (別の要素と等しくないことによって定義されます)。HashSet には、O(n)時間内にすべての要素を他のすべての要素と比較するより単純なアプローチに対して、時間内に重複除外プロセスを実行できるという利点もありますO(n^2)

mainList オブジェクトは可変であるため、のコードには変更されたリストが表示されます。メソッドが渡された引数の状態を変更すると、呼び出し元のコードはそれらの変更を認識します。

于 2013-10-16T14:19:51.640 に答える
2
  1. removeDuplicatessetを作成し、入力リストを反復処理します。入力リストに要素があり、それがセットにもある場合removeDuplicatesは、その要素を入力リストから削除します。そうでない場合は、その要素をセットに追加します。
  2. Java は参照渡し言語 (一種) です。つまり、メソッドは受け取っremoveDuplicatesた を変更できList<String> array、呼び出し元は への呼び出しがremoveDuplicates返された後にその変更されたリストを見ることができます。
于 2013-10-16T14:20:57.013 に答える
1

おそらく最も簡単な方法は、定義上重複を許可しない Set を最初に使用することです。

実際の問題については、いくつかのアプローチを実行できます。

  • 簡単だが時間のかかるアプローチ: 各要素 A をリスト内の他の各要素 N と比較します。A.equals(N) の場合、N を削除します。ヒント: A の前の各要素を既にチェックしているため、A をさらに各要素と比較するだけで済みます。

  • より高速なアプローチ: 自然な演算子を使用してリストを並べ替えます。これで、各要素 A と N を比較する必要がなくなり、A と次のいくつかの要素だけを比較できます。正確には、A と等しくない最初の要素が見つかるまで。この場合、(ソートのおかげで) A のそれ以上の重複はないと想定し、この次の要素を A として続行できます。

  • Map アプローチ (高速ですが、より多くのメモリを必要とします): リストに配置された各要素について、同じ要素を任意の Object を値として Map に配置します。これで、その要素が既にマップに含まれているかどうかを調べることができ、含まれている場合は重複しています。

ソートが非常に高速で、各要素を一度だけ取得する必要があり、2 番目のリストは必要ないため、2 番目のアプローチが最善の方法です。

編集: コードの 2 番目のアプローチ:

static void removeDuplicates(List<String> array) {
  if (array.size() <= 1) {
    return;
  }
  Collections.sort(array);
  final Iterator<String> it = array.iterator();
  String a = it.next(), n;
  while (it.hasNext()) {
    n = it.next();
    if (((a == null) && (n != null))
            || ((a != null) && (a.equals(n) == false))) {
      a = n;
    } else {
      it.remove();
    }
  }
}
于 2013-10-16T14:22:12.623 に答える
1

Seta を使用せずに使用するだけで同じことを行う方法は次のとおりですequals()(また、 a の初期化に関する「編集」の質問にいくらか答えるためにList):

  public static void main(String[] args) {
    List<String> list = new ArrayList<String>(Arrays.asList(new String[] {
        "good", "better", "best", "best", "first", "last", "last", "last",
        "good"}));
    removeDuplicates(list);
    for (String x : list) {
      System.out.println(x);
    }
  }

  static void removeDuplicates(List<String> array) {
    for (int i = 0; i < array.size(); i++) {
      String next = array.get(i);

      // check if this has already appeared before
      for (int j = 0; j < i; j++) {
        // if it has, stop the search and remove it
        if (next.equals(array.get(j))) {
          array.remove(i);
          // decrement i since we just removed the i'th element
          i--;
          // stop the search
          break;
        }
      }
    }
  }

HashSetとはいえ、すでに指摘されているように、より効率的であるため、を使用することをお勧めします。

の効率が必要であるHashSetが、それでもの順序を保持するList場合は、次のようにすることができます。

  static void removeDuplicates(List<String> array) {
    Set<String> set = new HashSet<String>();

    for (int i = 0; i < array.size(); i++) {
      String next = array.get(i);

      // check if this has already appeared before
      if (!set.add(next)) {
        // if it has then remove it
        array.remove(i);
        // decrement i since we just removed the i'th element
        i--;
      }
    }
  }
于 2013-10-16T14:30:26.317 に答える