Преобразование циклов с условиями в потоки - PullRequest
0 голосов
/ 05 ноября 2018

Я пытаюсь преобразовать обычный цикл, который я сделал несколько месяцев назад, в java 8 streams У меня мало знаний о потоке, поскольку я только начал использовать java 8 несколько дней назад.

Вот мой обычный цикл, который я хотел воссоздать в потоки

public static List<SmaliAnnotation> getAnnotations(List<String> lines, boolean hasPadding) {
    StringBuilder temp = new StringBuilder();
    List<SmaliAnnotation> annotations = new ArrayList<>();
    boolean shouldAdd = false;
    for (String line : lines) {
        String trim = hasPadding ? line.trim() : line;
        if (trim.isEmpty()) continue;
        if (trim.startsWith(".annotation")) {
            shouldAdd = true;
        }
        if (shouldAdd) {
            temp.append(line).append("\n");
        }
        if (trim.equalsIgnoreCase(".end annotation")) {
            shouldAdd = false;
            annotations.add(new SmaliAnnotation(temp.toString()));
            temp.setLength(0);
        }
    }
    return annotations;
}

Я начал преобразовывать его в потоки Java 8, но я застрял в shouldAdd части. Я не знаю, как этого добиться с помощью потоков. это моя попытка сделать потоки Java. Чего я не понимаю, так это как установить логическую часть из моего исходного цикла.

public static List<SmaliAnnotation> getAnnotations(List<String> lines, boolean hasPadding) {
    StringBuilder temp = new StringBuilder();
    boolean shouldAdd = false;
    return lines.stream()
            .filter(str -> str != null && !str.isEmpty())
            .map(line -> hasPadding ? line.trim() : line)
            .map(SmaliAnnotation::new)
            .collect(Collectors.toList());
}

Ответы [ 2 ]

0 голосов
/ 05 ноября 2018

Создайте вспомогательный класс, примерно так:

class Helper {
    StringBuilder temp = new StringBuilder();
    boolean shouldAdd = false;

    String checkStart(String line) {
       if (line.startsWith(".annotation")) {
          shouldAdd = true;
       }
       if (shouldAdd) {
          temp.append(line).append("\n");
       }
       return line;
   }

   SmaliAnnotation createAnnotation(String trim) {
        shouldAdd = false;
        SmaliAnnotation res = new SmaliAnnotation(temp.toString());
        temp.setLength(0);
        return res;
    }
}

тогда вы можете написать

StringBuilder temp = new StringBuilder();
Helper helper = new Helper();
return lines.stream()
        .filter(str -> str != null && !str.isEmpty())
        .map(line -> hasPadding ? line.trim() : line)
        .map(helper::checkStart)
        .filter(trim->trim.equalsIgnoreCase(".end annotation"))
        .map(helper::createAnnotation)
        .collect(Collectors.toList());

Вы можете минимизировать вспомогательный класс и попытаться встроить эти методы:

class Helper {
    boolean shouldAdd = false;
}

StringBuilder temp = new StringBuilder    Helper helper = new Helper();
return lines.stream()
        .filter(str -> str != null && !str.isEmpty())
        .map(line -> hasPadding ? line.trim() : line)
        .map((String line) -> {
           if (line.startsWith(".annotation")) {
              helper.shouldAdd = true;
           }
           if (helper.shouldAdd) {
              temp.append(line).append("\n");
           }
           return line;
        })
        .filter(trim->trim.equalsIgnoreCase(".end annotation"))
        .map((String trim) -> {
            helper.shouldAdd = false;
            SmaliAnnotation res = new SmaliAnnotation(temp.toString());
            temp.setLength(0);
            return res;
        })
        .collect(Collectors.toList());

Примечание. Я даже не пытался скомпилировать этот код.

0 голосов
/ 05 ноября 2018

Я превратил это в класс с методом обработки условных выражений. Причиной создания этого класса являются переменные temp, annotations и shouldAdd, к которым нужно обращаться через метод doStuff. Вам нужно еще немного это исправить ... назовите doStuff как-нибудь подходящее и т. Д. Возможно, есть лучший способ сделать это, но он использует потоки для того, что можно сделать с потоками.

public class AnnotationBuilder {
    private StringBuilder temp = new StringBuilder();
    private List<SmaliAnnotation> annotations = new ArrayList<>();
    private boolean shouldAdd;

    private AnnotationBuilder() {
        // no-op
    }

    public static List<SmaliAnnotation> getAnnotations(List<String> lines, boolean hasPadding) {
        return new AnnotationBuilder().build(lines, hasPadding);
    }

    private List<SmaliAnnotation> build(List<String> lines, boolean hasPadding) {
        lines.stream().map(line -> hasPadding ? line.trim() : line).filter(line -> !line.isEmpty()).forEach(line -> doStuff(line));
        return annotations;
    }

    private void doStuff(final String cleanLine) {
        if (cleanLine.startsWith(".annotation")) {
            shouldAdd = true;
        }
        if (shouldAdd) {
            temp.append(cleanLine).append("\n");
        }
        if (cleanLine.equalsIgnoreCase(".end annotation")) {
            shouldAdd = false;
            annotations.add(new SmaliAnnotation(temp.toString()));
            temp.setLength(0);
        }
    }
}
...