我有一个数组如下:
int[] array = {11, 14, 17, 11, 48, 33, 29, 11, 17, 22, 11, 48, 18};
我想要做的是找到重复的值,并打印出来。
所以我这样做的方法是转换为ArrayList
,然后转换为Set
并使用stream
上的Set
。
ArrayList<Integer> list = new ArrayList<>(array.length);
for (int i = 0; i < array.length; i++) {
list.add(array[i]);
}
Set<Integer> dup = new HashSet<>(list);
然后我使用stream
循环浏览并使用Collections.frequency
打印值。
dup.stream().forEach((key) -> {
System.out.println(key + ": " + Collections.frequency(list, key));
});
当然,即使计数为1,也会将它们全部打印出来。
我想加入if(key > 1)
,但这是我想要的价值而不是关键。
如何才能使此实例中的值仅在value > 2
。
我可能会投入:
int check = Collections.frequency(list, key);
if (check > 1) {
但是这会在Collections.frequency(list, key)
中复制stream
并且非常丑陋。
答案 0 :(得分:7)
您可以使用filter
仅获取大于2的值:
dup.stream()
.filter(t -> Collections.frequency(list, t) > 2)
.forEach(key -> System.out.println(key + ": " + Collections.frequency(list, key)));
结果你的情况是:
11: 4
修改
另一种解决方案:
无需使用Set
或Collections.frequency
即可使用:
Integer[] array = {11, 14, 17, 11, 48, 33, 29, 11, 17, 22, 11, 48, 18};
Arrays.stream(array).collect(Collectors.groupingBy(p -> p, Collectors.counting()))
.entrySet().stream().filter(t -> t.getValue() > 1)
.forEach(key -> System.out.println(key.getKey() + ": " + key.getValue()));
输出
48: 2
17: 2
11: 4
答案 1 :(得分:4)
完整示例没有在循环中初始化dup
并为每个唯一元素调用Collections.frequency
一次:
Integer[] array = {11, 14, 17, 11, 48, 33, 29, 11, 17, 22, 11, 48, 18};
List<Integer> list = Arrays.asList(array);
Arrays.stream(array).collect(Collectors.toSet())
.stream()
.map(v -> new SimpleEntry<>(v, Collections.frequency(list, v)))
.filter(v -> v.getValue() > 1)
.forEach(v -> System.out.println(v.getKey() + ":" + v.getValue()));
答案 2 :(得分:2)
这应该有效:
int[] array = {11, 14, 17, 11, 48, 33, 29, 11, 17, 22, 11, 48, 18};
List<Integer> list = Arrays.stream(array).boxed().collect(Collectors.toList());
// print values appearing more than once
list.stream().filter(i -> Collections.frequency(list, i) >1)
.collect(Collectors.toSet()).forEach(System.out::println);
会打印:
48
17
11
如果你也希望得到这样的事情:
int[] array = {11, 14, 17, 11, 48, 33, 29, 11, 17, 22, 11, 48, 18};
List<Integer> list = Arrays.stream(array).boxed().collect(Collectors.toList());
list.stream()
.filter(i -> Collections.frequency(list, i) >1)
.collect(Collectors.toMap(identity(), v -> 1, Integer::sum))
.forEach((x, y) -> System.out.println("Key: " + x +", occurence: "+ y));
打印
Key: 48, occurence: 2
Key: 17, occurence: 2
Key: 11, occurence: 4
答案 3 :(得分:2)
package various;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
public class Frequency {
public static void main(String[] args) {
int[] array = {11, 14, 17, 11, 48, 33, 29, 11, 17, 22, 11, 48, 18};
ArrayList<Integer> list = new ArrayList<>(array.length);
for (int i = 0; i < array.length; i++) {
list.add(array[i]);
}
Set<Integer> dup = new HashSet<>(list);
dup.stream().forEach((key) -> {
System.out.print((Collections.frequency(list, key) > 2) ? key + ": " + Collections.frequency(list, key) +"\n" : "");
});
}
}
输出:
11: 4
答案 4 :(得分:2)
HashMap<Integer, Integer> hashmap = new HashMap<>();
for (int i : array) {
if (hashmap.containsKey(i)) {
hashmap.put(i, hashmap.get(i) + 1);
} else {
hashmap.put(i, 1);
}
}
存储值及其频率。
{48=2, 17=2, 33=1, 18=1, 22=1, 11=4, 29=1, 14=1}
编辑:如果要打印重复项;
hashmap.entrySet().stream().filter((entry) -> ((int) entry.getValue() >= 2)).forEach((entry) -> {
System.out.println(entry.getKey() + ":" + entry.getValue());
});
给你:
48:2
17:2
11:4
答案 5 :(得分:2)
为了实现所需的功能,我们可以促进Java Streams,特别是Stream.collect
method:
<R> R collect(Supplier<R> supplier,
BiConsumer<R,? super T> accumulator,
BiConsumer<R,R> combiner)
请考虑以下草案实施:
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;
import java.util.stream.Collectors;
public class Program {
public static void main(final String[] args) {
// Input.
final int[] inputArray = {11, 14, 17, 11, 48, 33, 29, 11, 17, 22, 11, 48, 18};
// Processing.
final DuplicateCounter<Integer> duplicateCounter = Arrays.stream(inputArray)
.collect(
DuplicateCounter<Integer>::new,
DuplicateCounter<Integer>::accept,
DuplicateCounter<Integer>::combine
);
// Output.
System.out.println(duplicateCounter.getDuplicateCountMap());
}
private static final class DuplicateCounter<T> implements Consumer<T> {
private final Map<T, Integer> countMap = new HashMap<>();
public void accept(final T obj) {
this.incrementCounter(obj, 1);
}
public void combine(final DuplicateCounter<T> other) {
other.countMap.entrySet()
.forEach(entry -> this.incrementCounter(entry.getKey(), entry.getValue()));
}
public Map<T, Integer> getDuplicateCountMap() {
return this.countMap.entrySet()
.stream()
.filter(entry -> entry.getValue() > 1)
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}
private void incrementCounter(final T obj, int increment) {
final Integer counter = this.countMap.getOrDefault(obj, 0);
this.countMap.put(obj, counter + increment);
}
}
}
输出:
{48 = 2,17 = 2,11 = 4}
其他参考资料:
答案 6 :(得分:2)
还有另一种功能方式:
HashMap<Integer, Long> result = Arrays.stream(array)
.boxed()
.collect(Collectors.collectingAndThen(Collectors.groupingBy(
Function.identity(),
HashMap::new,
Collectors.counting()),
map -> {
map.entrySet().removeIf(x -> x.getValue() == 1);
return map;
}));
接受接受的答案 - 这可能是最糟糕的,就像对每个元素使用Collections.frequency
的每一个建议一样(即使是唯一的)
答案 7 :(得分:2)
相反,您可以使用流创建一个计算每个元素出现次数的地图,如下所示: 现在,如果您只想保留多次出现的值,您只需删除值等于 最后,如果你打印地图: 您将获得以下输出: 或者,以您期望的格式获得输出: 另一种方式,更短,没有流的开销: 然后,删除前面显示的唯一元素的条目:Collections.frequency
的问题是它必须遍历所有集合才能找到给定元素的频率。如果你为集合的每个元素执行,那么你的解决方案是O(n^2)
,即非常低效,因为处理时间会随着集合中元素数量的平方而增加。 / p>
int[] array = {11, 14, 17, 11, 48, 33, 29, 11, 17, 22, 11, 48, 18};
Map<Integer, Long> occurrences = Arrays.stream(array)
.boxed()
.collect(Collectors.groupingBy(
Function.identity(),
Collectors.counting()));
1
的地图条目:occurrences.values().removeIf(v -> v == 1);
System.out.println(occurrences);
{48=2, 17=2, 11=4}
occurrences.forEach((k, v) -> System.out.println(k + ": "+ v));
Map<Integer, Long> occurrences = new HashMap<>();
for (int n : array) occurrences.merge(n, 1L, Long::sum);
occurrences.values().removeIf(v -> v == 1);
答案 8 :(得分:1)
您可以使用过滤器:
dup.stream().filter(key -> Collections.frequency(list,key)>2).forEach(System.out::println);
答案 9 :(得分:1)
您根本不必将其转换为ArrayList。看看这个:
HashSet<Integer> set = new HashSet<Integer>();
for (int i = 0; i < array.length; i++) {
if(set.contains(array[i]))
System.out.println(array[i]);
else
set.add(array[i]);
}