使用Collections.frequency()打印某些值

我有一个数组如下:

int[] array = {11, 14, 17, 11, 48, 33, 29, 11, 17, 22, 11, 48, 18}; 

我想要做的是找到重复的值,并打印出来。

所以我这样做的方法是转换为ArrayList ,然后Set并使用Set上的stream

 ArrayList list = new ArrayList(array.length); for (int i = 0; i < array.length; i++) { list.add(array[i]); } Set 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) { 

但是这会在stream复制Collections.frequency(list, key)并且非常难看

也许你可以使用filter来获得大于2的值:

 dup.stream() .filter(t -> Collections.frequency(list, t) > 2) .forEach(key -> System.out.println(key + ": " + Collections.frequency(list, key))); 

结果你的情况是:

 11: 4 

编辑

另一种方案:

您无需使用SetCollections.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 

完整示例没有在循环中初始化dup并且为每个唯一元素调用Collections.frequency一次:

 Integer[] array = {11, 14, 17, 11, 48, 33, 29, 11, 17, 22, 11, 48, 18}; List 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())); 
 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 list = new ArrayList<>(array.length); for (int i = 0; i < array.length; i++) { list.add(array[i]); } Set dup = new HashSet<>(list); dup.stream().forEach((key) -> { System.out.print((Collections.frequency(list, key) > 2) ? key + ": " + Collections.frequency(list, key) +"\n" : ""); }); } } 

输出:

 11: 4 
 HashMap 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 

这应该工作:

 int[] array = {11, 14, 17, 11, 48, 33, 29, 11, 17, 22, 11, 48, 18}; List 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 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 

为了实现所需的function,我们可以促进Java Streams,特别是Stream.collect方法 :

  R collect(Supplier supplier, BiConsumer accumulator, BiConsumer 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 duplicateCounter = Arrays.stream(inputArray) .collect( DuplicateCounter::new, DuplicateCounter::accept, DuplicateCounter::combine ); // Output. System.out.println(duplicateCounter.getDuplicateCountMap()); } private static final class DuplicateCounter implements Consumer { private final Map countMap = new HashMap<>(); public void accept(final T obj) { this.incrementCounter(obj, 1); } public void combine(final DuplicateCounter other) { other.countMap.entrySet() .forEach(entry -> this.incrementCounter(entry.getKey(), entry.getValue())); } public Map 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}

其他参考:

  1. 减少(Java™教程>集合>聚合操作) 。
  2. Java 8 Streams – 收集与减少 。

而另一种function方式:

 HashMap 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每一个建议(即使是唯一的)

Collections.frequency的问题是它必须遍历所有集合才能找到给定元素的频率。 如果对集合的每个元素执行此操作,那么您的解决方案是O(n^2) ,即非常低效,因为处理时间随着集合中元素数量的平方而增加。

相反,您可以使用流创建一个计算每个元素出现次数的映射,如下所示:

 int[] array = {11, 14, 17, 11, 48, 33, 29, 11, 17, 22, 11, 48, 18}; Map occurrences = Arrays.stream(array) .boxed() .collect(Collectors.groupingBy( Function.identity(), Collectors.counting())); 

现在,如果您只想保留多于1次的值,则只需删除值等于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 occurrences = new HashMap<>(); for (int n : array) occurrences.merge(n, 1L, Long::sum); 

然后,删除前面显示的唯一元素的条目:

 occurrences.values().removeIf(v -> v == 1); 

您可以使用filter:

 dup.stream().filter(key -> Collections.frequency(list,key)>2).forEach(System.out::println); 

您根本不必将其转换为ArrayList。 看看这个:

 HashSet set = new HashSet(); for (int i = 0; i < array.length; i++) { if(set.contains(array[i])) System.out.println(array[i]); else set.add(array[i]); }