删除重复项(两个值) - 从ArrayList重复值

dan*_*ilo 17 java arraylist

我有ArrayList以下字符串;

 List<String> e = new ArrayList<String>();
 e.add("123");
 e.add("122");
 e.add("125");
 e.add("123");
Run Code Online (Sandbox Code Playgroud)

我想检查列表中的重复项并将其从列表中删除.在这种情况下,我的列表将只有两个值,在这个例子中,它将是值122和125,并且两个123将消失.

最好的方法是什么?我正在考虑使用a Set,但这只会删除其中一个副本.

Mar*_*oun 24

在Java 8中,您可以:

e.removeIf(s -> Collections.frequency(e, s) > 1);
Run Code Online (Sandbox Code Playgroud)

如果!Java 8你可以创建一个HashMap<String, Integer>.如果字符串已经出现在地图中,则将其增加1,否则将其添加到地图中.

例如:

put("123", 1);
Run Code Online (Sandbox Code Playgroud)

现在让我们假设您再次拥有"123",您应该获得密钥的计数并添加一个:

put("123", get("aaa") + 1);
Run Code Online (Sandbox Code Playgroud)

现在,您可以轻松地在地图上进行迭代,并使用其值<2的键创建新的数组列表.

参考文献:

  • Java 8版本确实有效,但只是因为它是一个`ArrayList`,并且`removeIf`被覆盖以在最后批量执行所有删除操作.例如,它不适用于`LinkedList`. (8认同)
  • `List :: removeIf`是一个干净的解决方案,但它的复杂性是'O(n²)`,因为迭代`List`和`Collection :: frequency`我是对的吗? (7认同)
  • 如果你创建一个`Map <String,Long>`来计算出现次数,然后迭代`EntrySet`来获得你有一个'O(2*n) - > O(n)`复杂度的唯一元素或者我错了吗? (6认同)

Saj*_*ran 11

您也可以filter在Java 8中使用

e.stream().filter(s -> Collections.frequency(e, s) == 1).collect(Collectors.toList())
Run Code Online (Sandbox Code Playgroud)


npi*_*nti 6

你可以用一个HashMap<String, Integer>.

迭代列表,如果哈希映射不包含字符串,则将其与值1一起添加.

另一方面,如果您已经拥有该字符串,则只需递增计数器即可.因此,您的字符串的映射将如下所示:

{"123", 2}
{"122", 1}
{"125", 1}
Run Code Online (Sandbox Code Playgroud)

然后,您将创建一个新列表,其中每个键的值为1.