【问题标题】:Using Java's built-in Set classes to count EACH(keyword) unique element in List values from a list使用 Java 的内置 Set 类从列表中计算列表值中的每个(关键字)唯一元素
【发布时间】:2013-08-07 05:00:15
【问题描述】:

给定一个可能包含重复项的列表(如下所示),我需要能够计算每个(关键字)唯一元素的数量。

List<String> list = new ArrayList<String>();
Set<String> set = new HashSet<String>();
list.add("M1");
list.add("M1");
list.add("M2");
list.add("M3");

set.addAll(list);
System.out.println(set.size());

如何从列表中获取每个唯一元素的计数? 这意味着我想知道 List(list) 中包含多少个“M1”,多少个“M2”等。

The result should be the following:
2 M1
1 M2
1 M3

【问题讨论】:

  • 建议编辑问题标题:“如何计算列表中项目的出现次数?”或类似的东西。

标签: java list set


【解决方案1】:

您正在寻找Map&lt;String, Integer&gt; 数据结构,而不是Set

类似

for(iterating over something){ 
    Integer count =map.get(value); 
    if( count == null){
          map.put(value, 1);


    } else{
        count++;
        map.put(value, count);
    }

}

Map是唯一映射到值的数据结构

【讨论】:

  • 我如何在地图中计数?或在 Map 中添加相同的值?我以前从未使用过地图。)
  • 我建议将代码重构为每个循环只调用一次 map.get()。
  • count++ 在我看来很可疑。它是整数,而不是整数。这真的能达到你想要的效果吗?我认为 map.put(value, count + 1) 无论如何都会更容易阅读......
  • count++ 对Integer有效
  • 酷。我不知道(在我看来它总是很可疑):-)
【解决方案2】:

我认为你正在寻找这样的东西(我没有编译它,但它应该能让你朝着正确的方向前进):

List<String> list = ArrayList<>();
Map<String, Integer> counts = new HashMap<>();
// Fill list with values....

for (String item:list) {
    Integer count = counts.get(item);
    if (count == null) {
        // This is the first time we have seen item, so the count should be one.
        count = 1;
    } else {
        // Increment the count by one.
        count = count + 1;
    }
    counts.put(item, count);
}

// Print them all out.
for (Entry<String, Integer> entry : counts.entrySet()) {
    System.out.println(entry.getValue() + " " + entry.getKey());
}

【讨论】:

    【解决方案3】:

    Set 在这种情况下帮不了你,你需要一张地图:

    List<String> list = new ArrayList<String>();
    Set<String> set = new HashSet<String>();
    list.add("M1");
    list.add("M1");
    list.add("M2");
    list.add("M3");
    
    // ...
    
    Map<String, Integer> counts = new HashMap<String, Integer>();
    for(String element: list) {
        int currentCount;
        if(counts.contains(element)) {
            currentCount = counts.get(element) + 1;
        } else {
            currentCount = 1;
        }
        counts.put(element, currentCount);
    }
    
    // ...
    
    for(String element: counts.keySet()) {
        System.out.println("element: " + element + ", times appeared: " + counts.get(element));
    }
    

    【讨论】:

    • 我建议重构这段代码,不要在同一次迭代中同时调用 contains() 和 get()。此外,编写的代码重复计数,而不是计算每个项目出现在列表中的次数 - put(element,0) 应该是 put(element,1)。
    • 另外,您的打印循环不需要调用 get() - 只需遍历 entrySet()。获取/包含/等。速度很快,但不是免费的。
    • @Rob 关于您的第一条评论:全部有效,已修复。关于您的第二条评论:实际上调用了 get()。
    • 我的第二个建议是不要调用 get()。您想要遍历 Map 中的所有条目,最有效的方法是遍历 entrySet()。这样,您不必在对每个键调用 get() 时评估每个键的 hashcode() 和 equals() 方法。 Map.Entry 很丑陋,但它可以在基本上没有开销的情况下完成工作。
    • @Rob 我不打算更改那部分,因为代码仍然有效。但是,当您首先发现时,我会赞成您的回答。
    【解决方案4】:

    表示你想知道List(list)中有多少个“M1”,有多少个“M2”,不用set接口,可以用Map > 接口,因为 Map 包含键、值对格式,即地图数据结构。

     Map<key,Value>
    

    【讨论】:

    • 这个答案没有说明在地图上放什么。有关如何使用地图解决此问题的更多详细信息将使这成为更有用的答案。
    【解决方案5】:

    更简单的方法:使用Collections.frequency()

    System.out.println("M2: "+Collections.frequency(list,"M2");

    会输出

    M2: 1

    【讨论】:

      猜你喜欢
      • 2021-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-25
      • 2019-09-05
      • 2017-11-09
      • 2020-06-27
      • 1970-01-01
      相关资源
      最近更新 更多