获取Set的所有被拒绝的添加内容

时间:2017-01-27 13:34:23

标签: java list arraylist duplicates hashset

我对hashsets并不是很好,我想知道我是否能够使用.addAll方法检索hashets删除的重复项。所以在我的代码中,它要求用户输入最多20的值,如果它是-1,则中断。然后删除重复项并显示完成的列表。但现在我想显示已删除重复项的列表列表。例如:2 = 3个重复5 = 5个重复。这是我的代码:

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.Scanner;
import java.util.Set;

public class Question {
    public static void main(String[] args) {
        ArrayList<Integer> entries = new ArrayList<Integer>();
        Scanner input = new Scanner(System.in);
        int counter = 0;
        int sentinel = -1;
        while (entries.size() <= 20) {

            System.out.println("Please enter some numbers into the entries list");
            entries.add(input.nextInt());
            if (entries.get(counter) == sentinel) {
                entries.remove(counter);
                break;
            }
            System.out.println("You've added: " + entries.get(counter) + ". So far your list is as shows: " + entries);
            counter++;

        }

        System.out.println("The list is: " + entries);
        System.out.println("Checking for Duplicates...");

        Set<Integer> num = new LinkedHashSet<>(entries);
        num.addAll(entries); // The addAll method deletes duplicates
        System.out.println(num);
        entries.clear();
        entries.addAll(num);

        System.out.println("The Finished list is: " + entries);

    }

}

5 个答案:

答案 0 :(得分:5)

不幸的是,Set不会跟踪它拒绝的所有项目。您必须手动执行此操作。快速而肮脏的方法如下:

Set<Integer> noDuplicates = new LinkedHashSet<Integer>();
List<Integer> rejects = new ArrayList<Integer>();
for(Integer entry : entry) {
   if(!noDuplicates.add(entry)) { rejects.add(entry) }
}

请注意,add方法会返回false,并在尝试向Set添加重复元素时拒绝添加请求。

答案 1 :(得分:3)

除了what CKing suggests,这是正确的,你可能也有兴趣使用Guava的Multiset。这个系列是为你所描述的问题而精心打造的。您只需使用add()方法添加元素(就像您已经这样做):

Multiset<Integer> entries = HashMultiset.create();
entries.add(1);
entries.add(1);
...

然后,要计算重复项,您可以这样做:

for (Integer entry : entries.elementSet()) {
     int count = entries.count(entry);
     if (count > 1) {
         System.out.println(entry +" = "+count+" duplicates");
     }
}

Multiset(也称为“Bag”)保留重复元素,并且可以轻松返回每个元素的出现次数。如果您想要(唯一)元素的 Set ,您只需拨打elementSet(),如上所示。

当然,只有当您不介意导入外部库时才会这样做。

答案 2 :(得分:2)

在我看来,好像你只使用Set,因为它的性质不允许重复。

我相信List可能与Set一样好。您正在对数据进行一些统计。没关系。

一些示例代码,通过使用Java 8使用列表来显示统计信息:

  1. 收集唯一值

    entries.stream()
        .distinct()
        .collect(Collectors.toSet()); // or list or array or whatever you prefer
    
  2. 仅收集重复项

    entries.stream()
        .filter(i -> Collections.frequency(entries, i) > 1)
        .collect(Collectors.toSet());
    
  3. 如果您希望立即打印出来,请省略.collect(...)并使用类似.forEach(System.out::println)的内容。

    如果您因任何原因无法使用Java 8,那么获取重复列表的另一种简单方法也是:

    // unique values:
    Set<Integer> uniqueEntries = new HashSet<>(entries);
    
    // get only the duplicates:
    List<Integer> duplicates = new ArrayList<>(entries);
    duplicates.removeAll(uniqueEntries);
    

    如果您真的希望Set知道重复项的数量,那么您需要实现自己的Set,其中包含您添加的每个重复项的计数器。

答案 3 :(得分:1)

如果您使用entries.add(),如果条目已存在,则返回false。所以你需要不使用addAll()方法,但是通过调用entries.add()来“手动”添加每个元素,并计算它返回false的次数。

详细了解here

顺便说一下。 addAll()也只是迭代给定的列表并为每个条目调用add(); - )

答案 4 :(得分:0)

您可以创建

ArrayList<Integer> duplicates = new ArrayList<Integer>();

然后当你添加它时,你只需检查它是否已经在数组中,如果是,你将它添加到重复数组

in=input.nextInt();
entries.add(in);
    if (entries.get(counter) == sentinel) {
        if(entries.contains(in))
            Duplicates.add(entries);
        entries.remove(counter);
        break;
        }

编辑:Cking的答案更好,但是我会把它留下来,因为它可以让你知道发生了什么,因为它更接近你的代码。