Страницы

Поиск по вопросам

суббота, 11 января 2020 г.

Можно ли упростить цикл, используя java 9 или java 8?

#java #инспекция_кода #lambda #java_8


Можно ли как-то упростить этот цикл, используя java 9 или java 8?

for (String s : list) {
    if (s.indexOf("D") != -1) {
        numberList.addAll(getDoubleFromString(s));
    } else {
        if (s.indexOf(".") != -1) {
            numberList.add(new TypeSatellite(BigDecimal.valueOf(Double.valueOf(s))));
        } else {
            numberList.add(new TypeSatellite(Integer.valueOf(s)));
        }
    }
}

    


Ответы

Ответ 1



Давай-те сделаем оптимизации по шагам (основная сложность непонятно что принимают TypeSatellite и какой тип у numberList, поэтому напишу для object'a): 1) Можно заменить s.indexOf(...) != -1 на s.contains(...), то есть записать что-то вроде list.forEach(s -> { if (s.contains("D")) { numberList.addAll(getDoubleFromString(s)); } else { if (s.contains(".")) { numberList.add(new TypeSatellite(BigDecimal.valueOf(Double.valueOf(s)))); } else { numberList.add(new TypeSatellite(Integer.valueOf(s))); } } }); 2) Можно вынести общий код list.forEach(s -> { if (s.contains("D")) { numberList.addAll(getDoubleFromString(s)); } else { Object number = s.contains(".") ? BigDecimal.valueOf(Double.valueOf(s)) : Integer.valueOf(s); numberList.add(new TypeSatellite(number)); } }); 3) Вынесем общий функцию: list.forEach(s -> { numberList.addAll(getListNumber(s)); }); } private static Collection getListNumber(String s) { if (s.contains("D")) { return getDoubleFromString(s)); } else { Object number = s.contains(".") ? BigDecimal.valueOf(Double.valueOf(s)) : Integer.valueOf(s); return Collections.singleton(new TypeSatellite(number)); } } 4) последний шаг используем стрим numberList = list.stream().flatMap(::getListNumber ).collect(Collectors.toList()); private static Stream getListNumber(String s) { if (s.contains("D")) { return getDoubleFromString(s).stream(); } else { Object number = s.contains(".") ? BigDecimal.valueOf(Double.valueOf(s)) : Integer.valueOf(s); return Stream.of(new TypeSatellite(number)); } }

Ответ 2



Данный код действительно можно отредактировать с использованием Java 8. Для начала будем руководствоваться тем, что list объявлен следующим образом: List list Воспользуемся функциональным интерфейсом из java.util.function.Predicate Predicate containsDouble = s->s.contains("D"); Predicate containsDecimal = s->s.contains("."); Predicate containsInteger = containsDouble.or(containsDecimal).negate(); Первый устанавливает, содержит ли строка "D", второй - точку, третий будет истинным, если первые два одновременно ложны. Далее мы можем заполнить numberList с, используя Stream API. list.stream().filter(containsDouble).forEach(s -> numberList.addAll(getDoubleFromString(s))); list.stream().filter(containsDecimal).forEach(s -> numberList.add(new TypeSatellite(BigDecimal.valueOf(Double.valueOf(s))))); list.stream().filter(containsInteger).forEach(s -> numberList.add(new TypeSatellite(Integer.valueOf(s)))); Замечу, что при этом объект numberList должен быть final или effectively-final. Трудоёмкость алгоритма при этом останется прежней O(N).

Комментариев нет:

Отправить комментарий