WE_ALL_LOVE_SHOUTY_SNAKE_CASE_SO_I_WROTE_A_PROGRAM_FOR_IT !! 1!

足够了。这是这个问题的一个破烂致富。该模式非常简单,它接受一个String输入,验证它是否为数字,如果是数字,则将其转换为SHOUTY_SNAKE_CASE。 br />

这很简单,但这也是我第一次使用Java 8的流,因此我想对我的(简单)用法发表意见。

private static final String[] words = 
        new String[]{"zero","one","two","three","four","five","six","seven","eight","nine"};

public static String convertNumbersToWords(final String input) {

    if(input == null || !input.matches("^\d*$")){
        throw new IllegalArgumentException("input cannot be null or non-numerical.");
    }

    return input.chars()
             .mapToObj(c -> getWordFromCharCode(c).toUpperCase())
             .collect(Collectors.joining("_"));
}

private static String getWordFromCharCode(int code){
    return words[code - 48];
}


评论

这段代码中很少有SHOUTY_SNAKE_CASE变量和文本吗?!

我来到这里的期望是PCG,而不是CR。很失望。

@fluffy现在很简单。您在PCG上看到的徽标表示“未完全毕业”:p

@holroy是Java,不是LOLCODE。

ArnoldC绝对是专为吵闹的东西而制作的

#1 楼

由于您需要一组与数字对齐的LOUD_WORDS枚举集,最好是某种形式的数字索引...因此,用enum代替String[]似乎是完美的选择: />(我想您可以找出推导的结果。)性能方面。

由于您还尝试了Java 8的某些功能,因此您可能还想考虑使用Word.values()来消除Optional -validation:

enum Word {
    ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE;
}


如果您希望将if用作NullPointerException的值,则可以坚持使用null

评论


\ $ \ begingroup \ $
您如何建议从数字映射到字符串?每个通话是否都使用Word.values()[digit]?
\ $ \ endgroup \ $
–西蒙·福斯伯格
15年11月27日在21:47

\ $ \ begingroup \ $
@SimonForsberg是的.map(i-> Character.getNumericValue(i))。mapToObj(i-> Word.values()[i] .toString())...
\ $ \ endgroup \ $
– h.j.k.
15年11月28日在3:12

\ $ \ begingroup \ $
@ h.j.k。 Word.values()每次都会创建一个新数组。一次将所有值存储在一个数组中对我来说听起来更好,这并不像您将创建一个Word w = Word.THREE;。或任何东西。听起来像String []对我来说更好。
\ $ \ endgroup \ $
–西蒙·福斯伯格
15年11月28日在10:13

\ $ \ begingroup \ $
使用枚举表示实际输出值时会有些警惕。例如,如果您曾经希望支持其他非拉丁字符的语言,则可能会引起问题。使用String [](甚至是Map )对我来说在语义上也更正确,尽管这是有争议的。
\ $ \ endgroup \ $
–鲍勃
2015年11月29日0:36



#2 楼

为什么将它们存储为小写字母,仅在它们上调用toUpperCase?以您打算使用它们的形式存储它们,并为每个单词保存一个函数调用。将字符串以相同的方式存储
也将更容易理解。

#3 楼

我建议用code - 48代替有点低级的Character.getNumericValue

另一个考虑因素可能是使用guava的CharMatcher.DIGIT.matchesAllOf而不是使用regex来验证输入字符串,尽管我意识到使用库通常不是重点。
请注意,此方法也会为您传递数字值也大于9的数字(即罗马数字50),您必须考虑一种支持它们的方法。 (拆分为个位数?)

评论


\ $ \ begingroup \ $
建议图书馆是一个好主意! :)只是您需要谨慎,不要将整个评估集中在使用外部库上。但是您的回答很好,谢谢! :)
\ $ \ endgroup \ $
–IEatBagels
15年11月27日在15:40

\ $ \ begingroup \ $
可以将代码-48替换为代码-'0'吗? (这仍然不是完美的,但是更好的IMO)
\ $ \ endgroup \ $
– oliverpool
15年11月27日在16:31

\ $ \ begingroup \ $
@oliverpool:programmers.stackexchange.com/questions/303553/…:)
\ $ \ endgroup \ $
– Benjaminssp
15年11月27日在16:44

\ $ \ begingroup \ $
使用Character.isDigit进行过滤,使用Character.getNumericValue进行转换,然后再次过滤以限制为0-9的范围。
\ $ \ endgroup \ $
–大卫·康拉德(David Conrad)
15年11月27日在20:16

#4 楼

命名和方法分解

让我们看一下该方法签名:


public static String convertNumbersToWords(final String input) {



方法名称建议转换数字...它适用于“ 1234”之类的输入。与数字类型相反,输入是字符串,并且“ 1234”是一个数字,而不是复数,这有点不自然。

此外,该方法还执行以下两项操作:


验证输入仅包含数字
将数字转换为SHOUT_CASE


最好将其分解为两种方法,例如:

private static String convertValidatedDigitsToWords(final String digits) {
    return digits.chars()
            .mapToObj(ShoutySnake::getWordFromCharCode)
            .collect(Collectors.joining("_"));
}

public static String convertDigitsToWords(final String input) {
    if (input == null || !input.matches("\d*")) {
        throw new IllegalArgumentException("input cannot be null or non-numerical.");
    }
    return convertValidatedDigitsToWords(input);
}


...,也许为数字输入添加重载:提示:String.matches表示^$,无需在模式中包括它们。 >那么最好编译正则表达式。

public static String convertDigitsToWords(final int number) {
    if (number < 0) {
        throw new IllegalArgumentException("input must be non-negative");
    }
    return convertValidatedDigitsToWords(Integer.toString(number));
}


幻数48

在此代码中,48是幻数:


private static final Pattern pattern = Pattern.compile("\d*");

public static String convertDigitsToWords(final String input) {
    if (!pattern.matcher(input).matches()) {
        throw new IllegalArgumentException("input must be non-null and non-negative.");
    }
    return convertValidatedDigitsToWords(input);
}



通过引用'0',您可以轻松地降低其魔力: >

评论


\ $ \ begingroup \ $
太好了,将它与@benjaminssp的建议结合起来以用Character.getNumericValue替换代码48,我想您已经找到答案了:
\ $ \ endgroup \ $
–user1477388
15年11月28日在18:16

\ $ \ begingroup \ $
感谢@ user1477388,您的评论促使我添加了另一部分;-)(魔术数字48)
\ $ \ endgroup \ $
– janos
15年11月28日在18:22

#5 楼

名称convertNumbersToWords()不能清楚地反映该方法的作用。您可以使用convertNumbersToShoutySnakeCaseWords()之类的Java约定来执行此操作,也可以使用与CONVERT_NUMBERS_TO_SHOUTY_SNAKE_CASE_WORDS()之类的应用程序目的相匹配的方式来执行此操作

评论


\ $ \ begingroup \ $
如果您将幽默感放在专业之上,那么也可以选择snakeShouts()
\ $ \ endgroup \ $
–亚伦
15年11月27日在15:02

\ $ \ begingroup \ $
仅仅因为代码是关于喧闹和蛇案的事情,并不意味着代码本身应该是喧闹的。
\ $ \ endgroup \ $
–西蒙·福斯伯格
15年11月27日在21:46

#6 楼

我建议更改尚未提及的三种想法。怎么办呢? />也一样。您是否真的要允许空输入?我建议不要。用*替换+

^[0-9]*$



我喜欢静态导入。它并不是每个人的最爱,但我认为,它使代码更具可读性。这就是为什么这将是我的最终解决方案:

^[0-9]+$
^\d+$