【问题标题】:Java8: Create HashMap with character count of a StringJava8:使用字符串的字符数创建 HashMap
【发布时间】:2019-08-03 08:54:11
【问题描述】:

想知道有没有比如下计算给定字符串的字符数更简单的方法?

String word = "AAABBB";
    Map<String, Integer> charCount = new HashMap();
    for(String charr: word.split("")){
        Integer added = charCount.putIfAbsent(charr, 1);
        if(added != null)
            charCount.computeIfPresent(charr,(k,v) -> v+1);
    }

    System.out.println(charCount);

【问题讨论】:

  • 对于 ANSI 字符,您可以只拥有一个大小为 256 的数组并计算它。
  • @vivek_23 那会是哪个ANSI character set?还是您的意思是 ASCII 和 128?
  • @vivek_23 是 Windows 代码页 1252,而不是 ANSI。 Unicode 标准匹配前 256 个代码点的 iso-latin-1 字符集。引用 windows 代码页 1252 是不必要的复杂化,因为该代码页在 128-159 范围内不匹配。
  • @Holger 啊!感谢您的指正。删除了我之前的评论以避免混淆。

标签: java string collections hashmap


【解决方案1】:

计算字符串中每个字符出现次数的最简单方法,完全支持 Unicode (Java 11+)1

String word = "AAABBB";
Map<String, Long> charCount = word.codePoints().mapToObj(Character::toString)
        .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
System.out.println(charCount);

1) 完全支持 Unicode 的 Java 8 版本在答案的末尾。

输出

{A=3, B=3}

更新:对于 Java 8+(不支持来自补充平面的字符,例如表情符号):

Map<String, Long> charCount = IntStream.range(0, word.length())
        .mapToObj(i -> word.substring(i, i + 1))
        .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));

更新 2: 也适用于 Java 8+。

我错了,认为 codePoints() 直到 Java 9 才添加。它是在 Java 8 中添加到 CharSequence 接口的,所以它没有显示在 Java 8 中 String 的 javadoc 中,并且对于更高版本的 javadoc,显示为 added in Java 9

不过,Character.toString​(int codePoint) 方法直到 Java 11 才添加,所以要使用 Character.toString​(char c) 方法,我们可以在 Java 8 中使用 chars()

Map<String, Long> charCount = word.chars().mapToObj(c -> Character.toString((char) c))
        .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));

或者对于完整的 Unicode 支持,包括。补充平面,我们可以在 Java 8 中使用 codePoints()String(int[] codePoints, int offset, int count) 构造函数:

Map<String, Long> charCount = word.codePoints()
        .mapToObj(cp -> new String(new int[] { cp }, 0, 1))
        .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));

【讨论】:

  • 对不起,Java 8 有简单的方法吗?
  • 说到“完整的 Unicode 支持”和表情符号,值得指出的是,即使使用代码点也不一定能提供预期的语义。例如。 "ā̧?‍??" 有 10 个字符,7 个代码点,但只有三个字符;第一个表明这不仅仅是一个表情符号问题。我目前知道的唯一解决方案是处理 grapheme clusters,例如使用 Java 9+:Pattern.compile("\\X").matcher(example).results() .collect(Collectors.groupingBy(MatchResult::group, Collectors.counting())).
【解决方案2】:

希望得到帮助:Java 8 Stream & Collector:

    String word = "AAABBB";
    Map<Character, Integer> charCount = word.chars().boxed().collect(Collectors.toMap(
                    k -> Character.valueOf((char) k.intValue()),
                    v -> 1,
                    Integer::sum));
    System.out.println(charCount);

Output:
    {A=3, B=3}

【讨论】:

  • chars() 需要 Java 9,并且使用 codePoints() 而不是 chars() 已经在 13 分钟前发布的更好的解决方案。
  • @Andreas 同意codePoints()solution,但chars()introduce in java 8 String.chars()
  • 那将是CharSequence.chars(),而不是String.chars(),但我接受您的更正。 Javadoc for Java 11 show 方法添加到 Java 9 中的 String 中,这让我误入歧途。
【解决方案3】:

想通了,下面是另一种简单的方法。

Map<String, Integer> charCount = new HashMap();
    for(String charr: s.split("")){
        charCount.put(charr,charCount.getOrDefault(charr,0)+1);
}

【讨论】:

  • charCount.put(charr,charCount.getOrDefault(charr,0)+1); 可以简化为charCount.merge(charr, 1, Integer::sum); 顺便说一句,你应该使用new HashMap&lt;&gt;()...
【解决方案4】:
     String str = "Hello Manash";
    Map<Character,Long> hm = str.chars().mapToObj(c-> 
    (char)c).collect(Collectors.groupingBy(c->c,Collectors.counting()));
    System.out.println(hm);

【讨论】:

    【解决方案5】:

    试试这个:

        List<Character> chars=Arrays.asList('h','e','l','l','o','w','o','r','l','d');
        Map<Character,Long> map=chars.stream().map(c->c).
        collect(Collectors.groupingBy(c->c,Collectors.counting()));
        System.out.println(map);
    

    输出:

    {r=1, d=1, e=1, w=1, h=1, l=3, o=2}
    

    【讨论】:

      【解决方案6】:
      word.chars().mapToObj(c-> (char)c).collect(Collectors.groupingBy(Function.identity(),LinkedHashMap::new, Collectors.counting()));
      

      这将按照角色出现的顺序为您提供角色计数。

      【讨论】:

      • 您是否可以将您的代码 sn-p 格式化为已编码,以提高可读性?谢谢。
      • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
      【解决方案7】:

      尝试以下方法:

      方法一:

          String str = "abcaadcbcb";
          
          Map<Character, Integer> charCount = str.chars()
                  .boxed()
                  .collect(toMap(
                          k -> (char) k.intValue(),
                          v -> 1,         // 1 occurence
                          Integer::sum));
          System.out.println("Char Counts:\n" + charCount);
      

      方法二:

          String str = "abcaadcbcb";
          Map<Character, Integer> charCount = new HashMap<>();
          for (char c : str.toCharArray()) {
              charCount.merge(c,          // key = char
                      1,                  // value to merge
                      Integer::sum);      // counting
          }
          System.out.println("Char Counts:\n" + charCount);
      

      输出:

          Char Counts:
          {a=3, b=3, c=3, d=1}
      

      【讨论】:

      • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
      猜你喜欢
      • 2014-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-05
      • 2022-01-24
      • 2014-04-15
      相关资源
      最近更新 更多