Попытка наиболее динамичной возможно FizzBuzz в Java


Я пытался придумать наиболее динамичных fizzbuzz, что я могу.. и вот что я придумал:

public static void main(String[] args) {

    ultraFizzBuzz((Integer arg) -> {
        String retVal = "";
        if(arg % 3 == 0) { retVal += "fizz"; }
        if(arg % 5 == 0) { retVal += "buzz"; }
        return retVal;
    });
}

public static void ultraFizzBuzz(modConditions<Integer> tester) {

    for(int i = 1; i < 100; i++) {
        String result = tester.test(i);
        if(result != "")
            System.out.println(tester.test(i));
        else
            System.out.println(i);
    }
}

Здесь modConditions-это интерфейс с методом (тест), которая возвращает тип String.

Что я пытаюсь сделать, это создать супер динамическая функция, которая позволяет вам добавить столько шипит и гудит и трещит, как хотелось бы.. но думаю, в процессе случайно сделала так, что вы в конечном итоге писать 90% кода в лямбда-оператор каждый раз, когда вы хотите назвать это.

Я усложнять вещи? Это считается плохой практикой программирования?



213
3
задан 8 марта 2018 в 11:03 Источник Поделиться
Комментарии
3 ответа

Самая главная проблема у меня с вашим кодом, что это совершенно не удается достичь цели вы поставили перед собой. Это не динамичный вообще. В принципе, взять "нормальный" способ тела и положил его в лямбда-выражение, но эта лямбда теперь является сложной функцией, которая содержит всю бизнес-логику.

Динамично, вам понадобится коллекция (вероятно, список заказать) лямбда-выражений, которые каждая проверка одного входного значения и возвратить соответствующее строковое представление (например, "шипение" или "гудения" или "все" или пустая строка) и способ применить это полный список на один вход, накапливать результаты и проводить окончательную проверку, следует ли выводить эту строку или само целое.

Таким образом, Начните с чего-то вроде:

Function<Integer, String> fizz = i -> i % 3 == 0 ? "fizz" : "";
Function<Integer, String> buzz = i -> i % 5 == 0 ? "buzz" : "";
Function<Integer, String> barz = i -> i % 7 == 0 ? "barz" : "";
List<Function<Integer, String>> fizzBuzzList = Arrays.asList(fizz, buzz, barz);

И постарайтесь придумать код, который работает на такой список. Примечание: функция стандартного типа функция с целым числом в качестве входных данных и строку выходных данных. Не нужно определить свой собственный интерфейс.

Если вы добились этого, вы можете легко добавить еще одну функцию в список, чтобы проверить другое значение, а то вы уже достигли чего-то, что можно считать динамическими.

6
ответ дан 9 марта 2018 в 07:03 Источник Поделиться

Это неоптимально, и даже багги:


String result = tester.test(i);
if(result != "")
System.out.println(tester.test(i));
else
System.out.println(i);

Прежде всего, вы звоните test.test(i) опять же, без надобности, вместо использования result.

Во-вторых, result != "" это не хороший способ проверить на равенство строки. Вы полагаетесь на то, что "" в ultraFizzBuzz() и "" в лямда должна быть точно такой же объект, из-за постоянного бассейн. Если лямбда была написана с String retVal = new String(new char[] {}); вместо этого, тогда сравнение было бы сломать. Вы должны проверить, либо "".equals(result) или result.isEmpty().

Вы никогда не должны пропустить "необязательные" брекеты, как вы будете вносить свой вклад в будущее несчастного случая кодирования.

Здесь один лучше записать тело цикла:

String result = tester.test(i);
System.out.println("".equals(result) ? String.valueOf(i) : result);


Я ожидал, что метод, который называется test() чтобы возвращать логическое значение. Это удивительно, что она возвращает строку.

Я думаю, что делать modConditions интерфейс дженерик-это перебор. Если вы думаете, что вам может понадобиться для поддержки long или BigInteger (действительно?!), потом просто запишите его с помощью long или BigInteger. И если это не целое число, то в этот момент он не будет в любом случае FizzBuzz. YAGNI.

Поскольку вы уже используете лямбда, я бы порекомендовал писать этот код, используя Java 8 потоков. Это будет выглядеть более элегантно, и вы бы избежать боксе int в Integer.

5
ответ дан 9 марта 2018 в 05:03 Источник Поделиться

Я бы, наверное, создать следующими способами:

public static String singleUltraFizzBuzz(SortedMap<Integer, String> fizzBuzzes, int i) {
StringBuilder result = new StringBuilder();
bool isEmpty = true;

for(Map.Entry<String, Object> entry : fizzBuzzes.entrySet()) {
if(i % entry.getKey() == 0) {
result.append(entry.getValue());
isEmpty = false;
}
}

return isEmpty ? i.toString() : result.toString();
}

public static String ultraFizzBuzz(SortedMap<Integer, String> fizzBuzzes, int min, int max) {
String out = "";

for(int i = min; i < max; i++) {
out = out + singleUltraFizzBuzz(fizzBuzzes, i) + "\n";
}
}

который будет называться следующим образом:

SortedMap<Integer, String> fizzBuzzes = new TreeMap<>();
fizzBuzzes.put(3, "fizz");
fizzBuzzes.put(5, "buzz");
System.out.write(ultraFizzBuzz(fizzBuzzes, 1, 100));

-1
ответ дан 10 марта 2018 в 02:03 Источник Поделиться