java—如何仅捕获arraylist中的重复元素?

dwthyt8l  于 2021-06-29  发布在  Java
关注(0)|答案(6)|浏览(398)

所以,我有个问题。我需要把所有的副本都放在我的电脑里 ArrayList . 我不需要删除重复项,我需要将它们添加到另一个 ArrayList . 举个例子:

  1. ArrayList<String> var = new ArrayList<>();
  2. var.add("a");
  3. var.add("b");
  4. var.add("b");
  5. var.add("c");

如您所见,有两个重复的元素(b和b)。我需要将它们添加到另一个arraylist。
结果 ArrayList 在这种情况下应该 [b,b] . 我该怎么做?

vsikbqxv

vsikbqxv1#

您可以循环遍历arraylist并比较 indexOf 以及 lastIndexOf 价值观。如果它们相同,则列表中只有一个对象示例。否则,它就是一个复制品。

nwlqm0z1

nwlqm0z12#

你可以使用 HashMap 存储 String 在每次迭代中。
然后,对于出现多次的元素,添加它们 n 新时代的时代 List :

  1. List<String> var = new ArrayList<>();
  2. var.add("a");
  3. var.add("b");
  4. var.add("b");
  5. var.add("c");
  6. Map<String, Integer> map = new HashMap<>();
  7. for(String str : var) {
  8. if(map.containsKey(str))
  9. map.put(str, map.get(str)+1);
  10. else
  11. map.put(str, 1);
  12. }
  13. List<String> duplicates = new ArrayList<>();
  14. for (String str : var) {
  15. int count = map.get(str);
  16. if(count > 1) {
  17. duplicates.add(str);
  18. }
  19. }
  20. System.out.println(duplicates);

输出:

  1. [b,b]
展开查看全部
tcbh2hod

tcbh2hod3#

这个问题的正确答案是通过实现适当的equal和hash方法来使用集合中的集合。集合不允许重复。
https://docs.oracle.com/javase/tutorial/collections/interfaces/set.html

n9vozmp4

n9vozmp44#

方法1:
这样就足够了:

  1. for(String s : var )
  2. if(Collections.frequency(var, s) > 1)
  3. duplicates.add(s);

和溪流:

  1. var.stream().filter(s -> frequency(var, s) > 1).collect(toList());

运行示例:

  1. public static void main(String[] args) {
  2. List<String> var = Arrays.asList("a", "b", "b", "c");
  3. List<String> dup = var.stream().filter(s -> Collections.frequency(var, s) > 1).collect(Collections.toList());
  4. System.out.println(duplicates);
  5. }

输出:

  1. [b, b]

其思想如下,转到列表中,并为每个元素检查它们在列表中出现的频率,如果它们出现多次,则添加到重复列表中。
方法2:
一个不太干净但时间复杂度更高的解决方案是,按字符串的每个频率使用一个字符串Map,然后基于该Map构建复制列表:

  1. List<String> dup = new ArrayList<>();
  2. Map<String, Long> frequencies =
  3. var.stream()
  4. .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
  5. for (Map.Entry<String, Long> entry : frequencies.entrySet()){
  6. for(int i = 0; i < entry.getValue() && entry.getValue() > 1; i++)
  7. dup.add(entry.getKey());
  8. }

方法3:
线性时间复杂度 O(N) :

  1. Set<String> set = new HashSet <>();
  2. List<String> duplicates = new ArrayList<>();
  3. Set<String> is_duplicated = new HashSet <>();
  4. var.forEach(s -> {
  5. if(set.contains(s)) {
  6. is_duplicated.add(s);
  7. duplicates.add(s);
  8. }
  9. else
  10. set.add(s);
  11. });
  12. duplicates.addAll(is_duplicated);
  13. System.out.println(duplicates);

一个人可以利用 Set.add 方法语义,即:

  1. If this set already contains the element, the call leaves the set
  2. unchanged and returns {@code false}.

将上述代码缩短为:

  1. Set<String> set = new HashSet <>();
  2. List<String> duplicates = new ArrayList<>();
  3. Set<String> to_add = new HashSet<>();
  4. var.forEach(s -> {
  5. if(!set.add(s)) {
  6. to_add.add(s);
  7. duplicates.add(s);
  8. }
  9. });
  10. duplicates.addAll(to_add);
  11. System.out.println(duplicates);
展开查看全部
9nvpjoqh

9nvpjoqh5#

下面是我解决这个问题的方法:

  1. ArrayList<String> duplicates = (ArrayList<String>) var.stream()
  2. .filter((e) ->
  3. var.stream()
  4. .filter(e::equals)
  5. .count() > 1
  6. ).collect(Collectors.toList());

它使用原始的arraylist创建一个流( var )作为源,它过滤它。过滤器的 predicate 还为外部流中的每个元素创建一个相同的流,但这次它按与外部流中的当前元素等效的所有元素进行过滤。因此,假设在您的示例中,您在第一个“b”元素上,它遍历arraylist并构造一个只包含“b”s的流。然后它计算流中元素的数量,并Assert还剩下1个以上的元素。换句话说,它验证这个元素是重复的。如果该 predicate 失败,那么元素将从流中移除,因此当您将流收集回arraylist时,只剩下重复的元素。

bfrts1fy

bfrts1fy6#

您可以创建一个对所有元素进行分组的Map,然后从该Map中删除具有大小分组的条目 1 最后将列表集合转换为平面列表。而且,我不会用 var 作为标识符,因为在较新版本的java中它是保留类型名。
在代码中:

  1. Map<String, List<String>> map = yourInitialList.stream()
  2. .collect(Collectors.groupingBy(Function.identity()));
  3. map.values().removeIf(list -> list.size() == 1);
  4. List<String> result = map.values().stream()
  5. .flatMap(list -> list.stream())
  6. .collect(Collectors.toList());

如果还需要保留插入顺序,可以使用重载调整贴图的创建 Collectors.groupingBy :

  1. Map<String, List<String>> map = yourInitialList.stream()
  2. .collect(Collectors.groupingBy(
  3. Function.identity(),
  4. LinkedHashMap::new,
  5. Collectors.toList()));
展开查看全部

相关问题