我不断遇到需要/认为我需要通过Map或Set保存状态的解决方案。 例如创建一个返回在输入中找到重复项的方法
// non streams solution
public int[] getDuplicates(int[] input){
Set<Integer> allSet = new HashSet<Integer>();
Set<Integer> duplicates = new HashSet<Integer>();
int[] dups = new int[input.length];
int j = 0;
for (Integer i : input) {
if (!allSet.add(i)) {
if(duplicates.add(i)) {
dups[j++] = i;
}
}
}
return Arrays.copyOfRange(dups, 0, j);
}
不幸的是,我的Java 8 Streams解决方案正在使用HashSet进行过滤。我了解这不是“适当的”,因为它取决于状态。 没有国家提出建议或硬性规定吗?运行并行流时只是一个问题吗?有人可以建议一种不使用HashSet的方法吗?
public static int[] getDuplicatesStreamsToArray(int[] input) {
Set<Integer> allSet = new HashSet<>();
int[] dups = Arrays.stream(input)
.sequential() // prevents parallel processing
.unordered() // speed up distinct operation
.boxed() // int to Integer
.filter(n -> !allSet.add(n)) // passes dups, but uses STATE
.distinct() // uses internal Set of dups
.mapToInt(i -> i) // Integer back to int
.toArray();
return dups;
}
答案 0 :(得分:3)
如何?
基本上,创建类型为Map<Integer,Long>
的频率计数,并返回keys
大于1的那些value
。
public static int[] getDuplicatesStreamsToArray(int[] input) {
int[] dups = Arrays.stream(input).boxed().collect(
Collectors.groupingBy(Function.identity(),
Collectors.counting())).entrySet().stream().filter(
e -> e.getValue() > 1).mapToInt(
e -> e.getKey()).toArray();
return dups;
}
我误解了你以前想做什么。