我对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);
}
}
答案 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使用列表来显示统计信息:
收集唯一值
entries.stream()
.distinct()
.collect(Collectors.toSet()); // or list or array or whatever you prefer
仅收集重复项
entries.stream()
.filter(i -> Collections.frequency(entries, i) > 1)
.collect(Collectors.toSet());
如果您希望立即打印出来,请省略.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的答案更好,但是我会把它留下来,因为它可以让你知道发生了什么,因为它更接近你的代码。