Работа с StringBuilder через API Java 8 Streams - PullRequest
0 голосов
/ 08 мая 2018

Я пытаюсь удалить некоторые символы из StringBuilder. Метод работает отлично. Тем не менее, я хочу добиться того же с помощью API потоков Java-8. Текущий код является многословным. Есть ли способ рефакторинга второго метода removeCarryReturnsCharacters () через API потоков Java 8?

private static StringBuilder readEntireFileUsingStream(Path filePath) throws IOException {

    StringBuilder data = new StringBuilder(String.valueOf(Files.readAllLines(filePath, StandardCharsets.ISO_8859_1)));

    return removeCarryReturnsCharacters(data);

}

private static StringBuilder removeCarryReturnsCharacters(StringBuilder fileData){

    int endIndex = 1012;
    String needToRemove = "";
    long totDataChunkCount = fileData.length()/1014;
    long delCounter = 1;
    try{
        while (delCounter < totDataChunkCount) {
            needToRemove = fileData.substring(endIndex, endIndex + 2);
            if (needToRemove.equals("^^")) {
                fileData.delete(endIndex, endIndex + 2);
            }
            endIndex += 1012;
            delCounter++;
        }
    }catch(StringIndexOutOfBoundsException exp){
        throw exp;
    }
    return fileData;
}

Ответы [ 3 ]

0 голосов
/ 08 мая 2018
private static StringBuilder removeCarryReturnsCharacters(StringBuilder fileData) {
    Stream.iterate(1012, i -> i + 1012)
          .limit(fileData.length() / 1014)
          .sorted(Collections.reverseOrder())
          .forEach(e -> {
                if (fileData.substring(e, e + 2).equals("^^")) {
                    fileData.delete(e, e + 2);
                }
          });
    return fileData;
}
0 голосов
/ 08 мая 2018

Похоже, вы пытаетесь удалить ^^ из отдельных строк исходного файла. Вы можете решить эту проблему, используя только File.lines и Stream.map:

List<String> lines = Files.lines(filePath, StandardCharsets.ISO_8859_1)
.map(line -> {
    if (line.charAt(endIndex) == '^' && line.charAt(endIndex + 1) == '^') {
        return new StringBuilder(line).delete(endIndex, endIndex + 2).toString();
    } else {
        return line;
    }
})
.collect(Collectors.toList());

Полагаю, это может иметь худшую производительность по сравнению с

new StringBuilder(String.valueOf(Files.readAllLines(...)))

Однако readAllLines считывает все строки в список, но lines лениво заполняется по мере расходования потока.

В этом случае, если мы используем один большой StringBuilder - все данные читаются сначала и обрабатываются позже . Наоборот - в случае File.lines данные обрабатываются и считываются в одновременно . После того, как последняя строка файла будет прочитана и обработана потоковым конвейером - появится список строк файла с удаленными символами ^^.

0 голосов
/ 08 мая 2018

Текущий код не является многословным из-за отсутствия Stream API, но содержит множество ненужных операций:

  • начальное назначение needToRemove = ""; устарело
  • вы поддерживаете две избыточные переменные цикла, delCounter и endIndex
  • вы используете цикл while, несмотря на то, что у вас есть классический цикл подсчета с начальным оператором, условием и операцией приращения, точная вещь, циклы for созданы для
  • вы используете long переменные для значений, которые определенно никогда не превышают диапазон значений int
  • у вас есть устаревший try … catch блок, просто перебрасывающий пойманную исключительную ситуацию
  • вам не нужна переменная needToRemove для хранения объекта для однократного использования; Вы можете просто проверить if(fileData.substring(endIndex, endIndex + 2).equals("^^")) или, как я бы предпочел, проверить только два символа,
    if(fileData.charAt(endIndex)=='^' && fileData.charAt(endIndex+1)=='^')

Исправление всех этих проблем превратит метод в

private static StringBuilder removeCarryReturnsCharacters(StringBuilder fileData) {
    for(int endIndex = 1012; endIndex < fileData.length(); endIndex += 1012)
        if(fileData.charAt(endIndex) == '^' && fileData.charAt(endIndex+1) == '^')
            fileData.delete(endIndex, endIndex + 2);
    return fileData;
}

Я не думаю, что будет какое-то дополнительное преимущество от переписывания цикла для использования Stream API.

...