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

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

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

ArrayList<String> var = new ArrayList<>();
var.add("a");
var.add("b");
var.add("b");
var.add("c");

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

vsikbqxv

vsikbqxv1#

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

nwlqm0z1

nwlqm0z12#

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

List<String> var = new ArrayList<>();
var.add("a");
var.add("b");
var.add("b");
var.add("c");

Map<String, Integer> map = new HashMap<>();
for(String str : var) {
    if(map.containsKey(str))
        map.put(str, map.get(str)+1);
    else
        map.put(str, 1);
}

List<String> duplicates = new ArrayList<>();
for (String str : var) {
    int count = map.get(str);
    if(count > 1) {
        duplicates.add(str);
    }
}

System.out.println(duplicates);

输出:

[b,b]
tcbh2hod

tcbh2hod3#

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

n9vozmp4

n9vozmp44#

方法1:
这样就足够了:

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

和溪流:

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

运行示例:

public static void main(String[] args) {

    List<String> var = Arrays.asList("a", "b", "b", "c");
    List<String> dup = var.stream().filter(s -> Collections.frequency(var, s) > 1).collect(Collections.toList());         
    System.out.println(duplicates);
}

输出:

[b, b]

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

List<String> dup =  new ArrayList<>();
Map<String, Long> frequencies =
        var.stream()
           .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));

     for (Map.Entry<String, Long> entry : frequencies.entrySet()){
         for(int i = 0; i < entry.getValue() && entry.getValue() > 1; i++)
             dup.add(entry.getKey());
}

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

Set<String> set = new HashSet <>();
    List<String> duplicates = new ArrayList<>();
    Set<String> is_duplicated = new HashSet <>();
    var.forEach(s -> {
        if(set.contains(s)) {
            is_duplicated.add(s);
            duplicates.add(s);
        }
        else
          set.add(s);
    });
    duplicates.addAll(is_duplicated);
    System.out.println(duplicates);

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

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

将上述代码缩短为:

Set<String> set = new HashSet <>();
    List<String> duplicates = new ArrayList<>();
    Set<String> to_add = new HashSet<>();
    var.forEach(s -> {
        if(!set.add(s)) {
            to_add.add(s);
            duplicates.add(s);
        }
    });
    duplicates.addAll(to_add);
    System.out.println(duplicates);
9nvpjoqh

9nvpjoqh5#

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

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

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

bfrts1fy

bfrts1fy6#

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

Map<String, List<String>> map = yourInitialList.stream()
    .collect(Collectors.groupingBy(Function.identity()));

map.values().removeIf(list -> list.size() == 1);

List<String> result = map.values().stream()
    .flatMap(list -> list.stream())
    .collect(Collectors.toList());

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

Map<String, List<String>> map = yourInitialList.stream()
    .collect(Collectors.groupingBy(
             Function.identity(),
             LinkedHashMap::new,
             Collectors.toList()));

相关问题