我正在努力学习流和hashmap,在这样做的过程中,我想制作一个非常可伸缩的、非常干净的FizzBuzz版本,同时遵守的“清洁代码”一书。
public class Main {
public static void fizzBuzzHundredTimes(Map<String, Integer> fizzDivisor) throws ArithmeticException{
String output; // Avoid recreating String each iteration
for (int i = 1; i <= 100; i++) {
final int finalI = i; // Variables used in lambda functions need to be final.
output = fizzDivisor.entrySet()
.stream()
.filter(entry -> finalI % entry.getValue() == 0)
.map(entry -> entry.getKey())
.collect(Collectors.joining(""));
if (output.length() > 0) {
// the value was divisible.
System.out.println(output);
} else {
System.out.println(i);
}
}
}
public static void main(String[] args) {
Map<String, Integer> fizzMap = new HashMap<>();
fizzMap.put("Fizz",3);
fizzMap.put("Buzz",5);
fizzMap.put("Fuzz",7);
fizzMap.put("Bizz",11);
fizzMap.put("Biff",13);
try{
// Avoid negative numbers
fizzBuzzHundredTimes(fizzMap);
} catch(Exception e){
System.err.println(e + "Was thrown");
}
}
}发布于 2019-07-29 10:51:55
output.isEmpty()而不是检查它的长度。LinkedHashMap,它也预先确定元素的顺序。现在排序看起来是随机的(会是BuzzFizzFuzzBiffBizz吗?)还是FizzFuzzBiffBizzBuzz?)(从技术上讲,它是确定性的,但它基于字符串的哈希码,这似乎是随机的)System.err.println(e + "Was thrown");没有告诉您为什么会发生异常。我建议使用记录器(Slf4j / Log4j)并正确地记录异常,或者使用e.printStackTrace()使您更容易调试问题。但是,在您的最终版本中,您不需要任何异常处理,因为所有可能导致它们出现的错误都应该已经修复--因为这是一个基于纯逻辑的应用程序,没有网络调用之类的东西。String output; // Avoid recreating String each iteration每次迭代都要重新创建字符串。你没办法避免这种情况。你只宣布过一次。在尽可能小的范围内声明它是最好的做法,所以我建议只在初始化它时声明它。// Avoid negative numbers我看不出这个评论在写的位置有什么关系。负数由代码中的for-循环来防止.发布于 2019-07-30 14:01:16
为了提高可读性,我将代码分为以下三个函数:
public static void fizzBuzzNTimes(Map<String, Integer> fizzDivisor, int times) {
IntStream.rangeClosed(1,times)
.mapToObj(n-> ifEmpty( fizzBuzzForN(n,fizzDivisor), String.valueOf(n)) )
.forEach(System.out::println);
}
private static String fizzBuzzForN(int n, Map<String,Integer> fizzDivisor) {
return fizzDivisor
.entrySet()
.stream()
.filter(entry -> n % entry.getValue() == 0)
.map(Map.Entry::getKey)
.collect(Collectors.joining());
}
private static String ifEmpty (String value, String defaultValue) {
return value.isEmpty() ? defaultValue : value;
}发布于 2019-07-29 06:58:24
在Java8Streams的主题上,您可以用IntStream替换for循环,后者发出整数值流。
若要发出1到100 (包括在内)之间的值流:
IntStream.rangeClosed(1, 100)
.foreach(i -> {
//...
});https://codereview.stackexchange.com/questions/225101
复制相似问题