Проблема с рефакторингом Java if-for цикла-if в if-stream

  • Укажите подробную информацию о своей цели

Я хочу реорганизовать приведенный ниже код, используя Javastream().

    public String before(String input) {
        if (input.contains("to for loop")) {
            String[] splitBySpace = input.split(" ");
            for (String s : splitBySpace) {
                if (s.contains("a:")) {
                    String[] anotherSplit = s.split(":");
                    return anotherSplit[1];
                }
            }
        }
        return null;
    }
  • Что я пробовал:
    public String after(String input) {
        if (input.contains("to for loop")) {
            String[] splitBySpace = input.split(" ");
            return Arrays.stream(splitBySpace)
.filter(oneSplit -> oneSplit.contains("a:"))
.map(oneContains -> oneContains.split(";")[1])
.findFirst();
        }
        return null;
    }
  • Проблема:

К сожалению, реорганизованный метод выдает необязательное значение String вместо String, и его невозможно скомпилировать.

  • Вопрос?

Каков правильный метод рефакторинга с использованием потока Java?

Распакуйте Optional через get или orElse.

Slevin 11.04.2024 01:55

проверьте документацию Optional: например. или Еще |-| не уверен, нравится ли мне такое смешанное решение (непотоковое и потоковое)

user85421 11.04.2024 01:56
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
2
57
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

В этом случае поток кажется правильным, однако метод findFirst() имеет необязательный тип возвращаемого значения. Что вы можете сделать, это:

  1. Проверьте, не нашел ли метод то, что вы ищете, используя метод isEmpty() и создав исключение.
  2. Используйте метод orElse() для обработки случая, когда строка не найдена.
Ответ принят как подходящий

findFirst возвращает Optional, чтобы обозначить тот факт, что поток может не содержать элементов, и в этом случае возвращаемый Optional пуст. Императивный код вернет null, если цикл for не обнаружит ни одной строки, содержащей a:. Таким образом, вы можете использовать orElse(null) для преобразования Optional<String> в String, где null возвращается, если Optional пусто.

return Arrays.stream(splitBySpace)
        .filter(oneSplit -> oneSplit.contains("a:"))
        .map(oneContains -> oneContains.split(";")[1])
        .findFirst().orElse(null);

Также рассмотрите возможность преобразования всего этого метода в цепочку вызовов методов и возврата Optional<String> в конце вместо String, который может иметь значение null.

public Optional<String> after(String input) {
    // use ofNullable to gracefully handle a null input
    return Optional.ofNullable(input)
            // this filter is analogous to the if statement
            .filter(x -> x.contains("to for loop"))
            .stream()
            .flatMap(x -> Arrays.stream(x.split(" ")))
            .filter(oneSplit -> oneSplit.contains("a:"))
            .map(oneContains -> oneContains.split(";")[1])
            .findFirst();
}

Другие вопросы по теме