【问题标题】:Counting size of List by element [duplicate]按元素计算列表的大小[重复]
【发布时间】:2017-04-17 02:09:03
【问题描述】:

我想按元素计算 List 的大小。 例如,

List<String> source = Arrays.asList("USA", "USA", "Japan", "China", "China", "USA", "USA");

我想从这个来源创建对象(地图),例如,

int usa_count = result.get("USA").intValue(); // == 4
int javan_count = result.get("Japan").intValue(); // == 1
int china_count = result.get("China").intValue(); // == 2
int uk_count = result.get("UK").intValue(); // == 0 or NPE (both OK)

现在,我在下面作曲。

Map<String, Integer> result = new HashMap<>();
for (String str : source) {
    Integer i = result.getOrDefault(str, Integer.valueOf(0));
    result.put(str, i + 1);
}

虽然,这足以达到我的目的,但我认为这不是优雅的代码,我想成为一名优雅的编码员。 我使用Java8。 有什么优雅的解决方案可以代替我的解决方案吗?

【问题讨论】:

标签: java collections


【解决方案1】:

您可以使用流groupingBy,如下所示:

List<String> source = Arrays.asList("USA", "USA", "Japan", 
        "China", "China", "USA", "USA");

Map<String, Long> result =
                source.stream().collect(
                        //Use groupingBy
                        Collectors.groupingBy(
                                Function.identity(), Collectors.counting()
                        )
                );


System.out.println(result);

输出: {USA=4, China=2, Japan=1}

【讨论】:

    【解决方案2】:

    您可以在采集中使用频率法。

    int usa_count = Collections.frequency(source, "USA");
    int javan_count = Collections.frequency(source, "Japan");
    int china_count = Collections.frequency(source, "CHINA"); 
    int uk_count = Collections.frequency(source, "UK");
    

    参考:https://www.tutorialspoint.com/java/util/collections_frequency.htm

    Java 8 中:-

    groupingBy 收集器允许将具有相同分类的元素组合到一个地图中。

    Map<String, Long> countContries = source.stream().collect(Collectors.groupingBy(Function.identity() , Collectors.counting()));
    

    参考:https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html

    https://www.mkyong.com/java8/java-8-collectors-groupingby-and-mapping-example/

    【讨论】:

    • 虽然这不会构建地图...
    • 顺便说一句,您可以添加该函数的 javadoc 以使答案更有用
    【解决方案3】:

    您可以使用 Stream-api 来执行此操作。

    source.stream()
          .collect(Collectors.groupingBy(
                          Function.identity(), 
                          Collectors.counting());
    

    groupingBy-collector 生成一个映射,其中键由第一个参数给出。可以省略第二个参数以给出具有相同键的每个组的列表。在您的情况下,这将给出:

    Map("USA" -> List("USA", "USA", "USA", "USA"),
        "Japan" -> List("Japan"),
        "Chine" -> List("China", China"))
    

    通过给一个收集器作为参数,它将收集每个组(在这种情况下,计算元素的数量)。

    【讨论】:

      【解决方案4】:

      恕我直言,您的代码还可以,但可以稍微简化一下:

      Map<String, Integer> result = new HashMap<>();
      for (String str : source) {
          int i = result.getOrDefault(str, 0);
          result.put(str, i + 1);
      }
      

      甚至:

      Map<String, Integer> result = new HashMap<>();
      for (String str : source) {
          result.put(str, result.getOrDefault(str, 0) + 1);
      }
      

      【讨论】:

        猜你喜欢
        • 2023-03-11
        • 2011-05-07
        • 2019-08-01
        • 2020-06-27
        • 1970-01-01
        • 1970-01-01
        • 2019-04-12
        • 2018-06-21
        • 2016-05-12
        相关资源
        最近更新 更多