6

次のリストから、「wow」と「quit」だけが必要です。

List<String> list = new ArrayList();                
list.add("test");       
list.add("test");                   
list.add("wow");    
list.add("quit");
list.add("tree");
list.add("tree");
4

9 に答える 9

7

コレクション内の要素の頻度を確認し、頻度が 1 を超える要素を除外できます。

   List<String> list = new ArrayList<String>();
    list.add("test");       
    list.add("test");                   
    list.add("wow");    
    list.add("quit");
    list.add("tree");
    list.add("tree");
    for(String s: list){
        if(Collections.frequency(list, s) == 1){
            System.out.println(s);
        }

出力:

wow
quit
于 2013-01-08T22:44:23.297 に答える
4

outputこのスニペットにより、リストの重複していない要素のみを含むセット ( ) が残るはずです。

HashSet<String> temp = new HashSet<String>();
HashSet<String> output = new HashSet<String>();

for (String element : list)
{
    if (temp.contains(element)) output.remove(element);
    else
    {
        temp.insert(element);
        output.insert(element);
    }
}

O(n*log(n)) 時間で動作します: リスト内の n 個の要素のそれぞれに対して、1 セットの対数演算 (セット ルックアップ、挿入など)。

于 2013-01-08T22:44:37.990 に答える
3

HashMap implを使用して、発生をカウントし、1回だけ発生するものを選択できます。

例えば

void check(List<String> list)
{
  Map<String,Integer> checker = new HashMap<String,Integer>();
  List<String> result = new ArrayList<String>();
  for(String value: list)
  {
    Integer count = checker.get(value); 
    if (count==null)
    {
      count = 0;
    }
    checker.put(value, ++count);
  }
  // now select only values with count == 1
  for(String value: checker.keySet())
  {
    if (checker.get(value) == 1)
    {
      result.add(value);
    }
  }
  System.out.println(result); 
}
于 2013-01-08T22:52:56.260 に答える
2

そして第三の道

List result = new ArrayList();
for(Object o : list){
   if(list.indexOf(o) == list.lastIndexOf(o))
   result.add(o);
}
于 2013-01-08T22:46:01.733 に答える
2

ストリームのないJava 8の方法は次のとおりです。

Map<String, Long> counts = new HashMap<>();
list.forEach(word -> counts.merge(word, 1L, Long::sum));

counts.values().removeIf(count -> count > 1);

これは最初にリストを反復し、各単語の頻度をcountsマップに格納します。このために、指定Map.mergeされた値 (1Lこの場合) を指定されたキー (wordここ) に関連付けるか、指定されたマージ関数 ( Long::sum) を使用して既存の値を指定された値と結合するメソッドを使用しています。

次に、より頻度の高い単語が、メソッド1を介してマップから削除されます。Collection.removeIf

プロセス全体にO(n)時間の複雑さがあります。

于 2018-03-22T21:40:30.403 に答える
1

@ ROMANIA_Engineer のソリューションは問題なく動作するはずですが、O(n) 操作であるため、O(n 2 ) の複雑さが隠されています。Collections.frequency

1 つのステートメントに絞り込むことができるより効率的な解決策は、各項目の発生回数をカウントし、1 回だけ表示される項目のみをフィルター処理することです。

list.stream()
    .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
    .entrySet()
    .stream()
    .filter(e -> e.getValue() == 1L)
    .map(Map.Entry::getKey)
    .forEach(System.out::println);
于 2018-03-22T21:02:17.960 に答える