如何使用HashMap忽略字符串中的空格,大写字母和标点符号?

时间:2018-03-21 20:58:09

标签: java string collections hashmap

Hello我正在尝试使用HashMap编写计算给定字符串中所有字符的程序,然后在控制台上打印结果,如:

{a = 2,s = 2,k = 1,m = 1,o = 1}

到目前为止,我有这样的事情:

public void result(String sentence) {
    int value;
    HashMap<Character, Integer> mp = new HashMap<Character, Integer>();
    for (int i = 0; i < sentence.length(); i++) {
        if (mp.containsKey(sentence.charAt(i))) {
            value = mp.get(sentence.charAt(i));
            value++;
            mp.put(sentence.charAt(i), value);

        } else {
            mp.put(sentence.charAt(i), 1);
        }
    }

    System.out.print(mp);
}

我想问一下如何忽略给定字符串中的空格,大写字母和标点符号。 所以它不会显示在结果中?

我希望有人能帮助我,谢谢你!

3 个答案:

答案 0 :(得分:5)

我建议您在将字符传递到HashMap之前过滤掉您不想要的字符。

例如,

sentence = sentence.replaceAll("[^a-z]", "");

除了小写字母和

之外,还会删除任何内容
sentence = sentence.replaceAll("[^a-z0-9]", "");

会留下小写字母和数字。

如果要将大写字母转换为小写而不是忽略它们,请先使用

sentence = sentence.toLowerCase();

答案 1 :(得分:0)

您可以检查当前字符的ascii值,以及它是否在给定范围内&#39; a&#39; (97)和&#39; z&#39; (122)你会把它添加到地图上,否则你会忽略它。

    if (mp.containsKey(sentence.charAt(i))) {
        ...
    } else if(sentence.charAt(i) >= 'a' || sentence.charAt(i) <= 'z') {
        mp.put(sentence.charAt(i), 1);
    } else {
        System.out.println("Ignoring - " + sentence.charAt(i));
    }

这样可以防止任何额外遍历句子并在创建地图之前进行清理。 O(1)

答案 2 :(得分:0)

这就是我接近任务的方式:

public static void main(String[] args) {
    String source = "Here comes another challenger!";
    Map<Character, Integer> characterCounts = countCharacters(source);
    System.out.println("Source string \"" + source + "\" gives map:\n"
            + characterCounts);
}

public static Map<Character, Integer> countCharacters(String source) {
    Map<Character, Integer> characterCounts = new HashMap<>(64);
    source.chars().map(LetterCounter::lowercaseCharacter).filter(
            LetterCounter::isCharactedCounted).forEach(c
                    -> characterCounts.merge((char) c, 1, (o, n) -> o + 1));
    return characterCounts;
}

public static int lowercaseCharacter(int characterValue) {
    char character = (char) characterValue;
    return (int) Character.toLowerCase(character);
}

public static boolean isCharactedCounted(int character) {
    if (character >= 'a' && character <= 'z') {
        return true;
    }
    return false;
}

运行示例main方法会得到输出:

Source string "Here comes another challenger!" gives map:
{a=2, c=2, e=6, g=1, h=3, l=2, m=1, n=2, o=2, r=3, s=1, t=1}

countCharacters方法正在创建给定String中找到的IntStream个字符,但这只是一种优雅/紧凑/懒惰的方式,与您正在执行的操作完全相同for循环。 Stream.map方法调用lowercaseCharacter(int)int字符值转换为小写字符int值。然后,filter方法会丢弃导致方法isCharactedCounted返回false的所有字符,因为我们不需要这些字符。然后forEach用于处理我们感兴趣的字符串中的每个字符(每次在字符串中找到字符时调用forEach中的代码)。 Map.merge方法只是一种优雅/紧凑/懒惰的方式,可以完全按照你的get,++,put代码进行操作。然后返回完成的地图。

您可以自定义isCharacterCounted方法以满足您的需求。请注意,此方法采用int原语而非char(因为String.chars()方法返回int的流而不是char的流。但是,在Java中,char实际上只是int,所以这两者基本上是可以互换的,只要你记得在需要时使用正确的类型转换。 (请注意,在调用Map.merge时,我们必须将int c转换为(char) c,因为地图需要Characterint无法自动转换为Character加载到lowercaseCharacter。我们需要创建实用工具方法int以将int字符值转换为小写.bubble { display: inline-block; position: relative; width: 35px; height: 20px; padding: 0px; background: rgb(219, 218, 218); -webkit-border-radius: 16px; -moz-border-radius: 16px; border-radius: 16px; border:rgb(107, 107, 107) solid 2px; } .bubble:after { content: ''; position: absolute; border-style: solid; border-width: 6px 5px 0; border-color: rgb(219, 218, 218) transparent; display: block; width: 0; z-index: 1; margin-left: -5px; bottom: -6px; left: 43%; } .bubble:before { content: ''; position: absolute; border-style: solid; border-width: 7px 6px 0; border-color: rgb(107, 107, 107) transparent; display: block; width: 0; z-index: 0; margin-left: -6px; bottom: -9px; left: 43%; } .bubble:hover { background-color: red; }字符值。)