首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Collections.frequency()打印某些值

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

Stack Overflow用户
提问于 2017-11-17 15:06:52
回答 10查看 3.9K关注 0票数 6

我有如下数组:

代码语言:javascript
复制
int[] array = {11, 14, 17, 11, 48, 33, 29, 11, 17, 22, 11, 48, 18};

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

因此,我的方法是将其转换为ArrayList,然后转换为Set,并在Set上使用stream

代码语言:javascript
复制
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

代码语言:javascript
复制
dup.stream().forEach((key) -> {
            System.out.println(key + ": " + Collections.frequency(list, key));
        });

它当然会把它们全部打印出来,即使计数是1。

我想添加if(key > 1),但这是我想要的值,而不是关键。

如何获得此实例中的值,以便只在何处打印value > 2

我也许可以放进去:

代码语言:javascript
复制
int check = Collections.frequency(list, key);
            if (check > 1) {

但是,这与Collections.frequency(list, key)stream中的复制是非常丑陋的。

EN

回答 10

Stack Overflow用户

回答已采纳

发布于 2017-11-17 15:20:15

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

代码语言:javascript
复制
dup.stream()
       .filter(t -> Collections.frequency(list, t) > 2)
       .forEach(key -> System.out.println(key + ": " + Collections.frequency(list, key)));

就你的情况而言,结果是:

代码语言:javascript
复制
11: 4

编辑

另一种解决办法是:

不需要使用SetCollections.frequency,您只需使用:

代码语言:javascript
复制
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()));

输出

代码语言:javascript
复制
48: 2
17: 2
11: 4
票数 7
EN

Stack Overflow用户

发布于 2017-11-17 15:31:45

不需要在循环中初始化dup并为每个唯一元素调用Collections.frequency的完整示例如下:

代码语言:javascript
复制
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()));
票数 4
EN

Stack Overflow用户

发布于 2017-11-18 23:17:12

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

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

代码语言:javascript
复制
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次的值,则只需删除值等于1的映射项。

代码语言:javascript
复制
occurrences.values().removeIf(v -> v == 1);

最后,如果您打印地图:

代码语言:javascript
复制
System.out.println(occurrences);

您将得到以下输出:

代码语言:javascript
复制
{48=2, 17=2, 11=4}

或者,要以您期望的格式获得输出:

代码语言:javascript
复制
occurrences.forEach((k, v) -> System.out.println(k + ": "+ v));

另一种方式,短得多,没有流的开销:

代码语言:javascript
复制
Map<Integer, Long> occurrences = new HashMap<>();
for (int n : array) occurrences.merge(n, 1L, Long::sum);

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

代码语言:javascript
复制
occurrences.values().removeIf(v -> v == 1);
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47353687

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档