замена пары циклов Java на простую лямбду, но это выглядит как слишком сложный - PullRequest
0 голосов
/ 17 января 2019

Я работаю с некоторыми файлами Apache POI, он работает, и я делаю некоторый рефакторинг по этому вопросу, но я сталкиваюсь с сомнением с этим кодом:

for (XWPFTable tbl : doc.getTables()) {
                for (XWPFTableRow row : tbl.getRows()) {
                    for (XWPFTableCell cell : row.getTableCells()) {
                        for (XWPFParagraph paragraph : cell.getParagraphs()) {
                            for (XWPFRun xwpfRun : paragraph.getRuns()) {
                                String text = xwpfRun.getText(0);
                                if (text != null && text.contains(key)) {
                                    text = text.replace(key, replaces.get(key) == null ? "" : replaces.get(key));
                                    xwpfRun.setText(text, 0);
                                }
                            }
                        }
                    }
                }
            }

Когда я пытаюсь заменить это лямбда-кодом, код выглядит так:

    List<XWPFRun> collect = doc.getTables().stream().flatMap(xwpfTable -> xwpfTable.getRows().stream()
                    .flatMap(xwpfTableRow -> xwpfTableRow.getTableCells().stream().
                            flatMap(xwpfTableCell -> xwpfTableCell.getParagraphs().stream()
                                    .flatMap(xwpfParagraph -> xwpfParagraph.getRuns().stream().filter(Objects::nonNull)))))
                    .collect(Collectors.toList());

И для меня этот код действительно сложен, так как он не возвращает ничего, что мне нужно разделить по одному для каждого:

 for (XWPFRun xwpfRun : paragraph.getRuns()) {
                                String text = xwpfRun.getText(0);
                                if (text != null && text.contains(key)) {
                                    text = text.replace(key, replaces.get(key) == null ? "" : replaces.get(key));
                                    xwpfRun.setText(text, 0);
                                }
                            }

Я почти уверен, что есть лучший и более чистый способ сделать это, но я не мог понять это, у вас есть какие-нибудь идеи?

Ответы [ 2 ]

0 голосов
/ 17 января 2019
  1. Вы можете сделать flatMap один за другим
  2. Упростите код в forEach в конце
    • удалить условие text.contains(key)
    • используйте getOrDefault вместо троичной операции, которая в случае успеха получит двойной доступ к карте
doc.getTables().stream()
            .flatMap(xwpfTable -> xwpfTable.getRows().stream())
            .flatMap(xwpfTableRow -> xwpfTableRow.getTableCells().stream())
            .flatMap(xwpfTableCell -> xwpfTableCell.getParagraphs().stream())
            .flatMap(xwpfParagraph -> xwpfParagraph.getRuns().stream())
            .filter(Objects::nonNull)
            .forEach(xwpfRun -> {
                String text = xwpfRun.getText(0);
                if (text != null) {
                    xwpfRun.setText(text.replace(key, replaces.getOrDefault(key, "")), 0);
                }
            });
0 голосов
/ 17 января 2019

Вы очень близки к удобочитаемому решению.

Вы можете "расплющить" ваши flatMap звонки так:

doc.getTables().stream()
        .map(XWPFTable::getRows).flatMap(List::stream)
        .map(XWPFTableRow::getTableCells).flatMap(List::stream)
        .map(XWPFTableCell::getParagraphs).flatMap(List::stream)
        .map(XWPFParagraph::getRuns).flatMap(List::stream)
        .filter(Objects::nonNull)
        .forEach(xwpfRun -> {
            String text = xwpfRun.getText(0);
            if (text != null && text.contains(key)) {
                text = text.replace(key, replaces.get(key) == null ? "" : replaces.get(key));
                xwpfRun.setText(text, 0);
            }
});

Или вы можете заменить каждый .map().flatMap() на .flatMap, что немного больше похоже на ваше решение. Например:

.flatMap(table -> table.getRows().stream())
.flatMap(row -> row.getTableCells().stream())
...

Вы также можете добавить .filter вместо оператора if в forEach, но, на мой взгляд, это выглядело более сложным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...