Найти каждый столбец в таблице в моем потоке Java 8 - PullRequest
0 голосов
/ 10 января 2019

Я использую HtmlUnit, чтобы получить HtmlTable. Я пытаюсь получить список ячеек каждого столбца.

Пока что в коде, который я пробовал, я могу найти первый столбец. Как я могу перебрать каждый столбец и запустить в них код?

Я бы хотел убедиться, что все они отсортированы по алфавиту, но мне просто нужно выяснить, где разместить этот код.

РЕДАКТИРОВАТЬ: Я нашел свой ответ. Я думаю, что сформулировал вопрос неправильно. Мне нужно было получить каждый столбец и поместить их в свою коллекцию. В исходном примере я показал только column1. Но мне нужен КАЖДЫЙ столбец (основанный на количестве ячеек в каждом ряду). Ниже приведен код, который работал. Но он может быть лучше оптимизирован.

HtmlPage htmlPage = webClient.getPage("http://localhost:8080/myurl");

    HtmlTable myTable = htmlPage.getHtmlElementById("mytable");

    // find the number of columns by grabbing the first row and returning the number
    // of cells within the first row
    int numberOfColumns = myTable.getRows().stream().map(row -> row.getCells()).findFirst().get()
            .size();

    // initialize columns
    List<List<String>> columns = new ArrayList<List<String>>(numberOfColumns);

    // initialize new arraylists for each column based upon the number of columns
    for (int i = 0; i < numberOfColumns; i++)
        columns.add(new ArrayList<>());

    // iterate through each column
    for (int columnIndex = 0; columnIndex < numberOfColumns; columnIndex++) {

        // iterate through each row
        for (int rowIndex = 0; rowIndex < myTable.getRows().size(); rowIndex++) {

            String asText = myTable.getCellAt(rowIndex, columnIndex).asText();
            columns.get(columnIndex).add(asText);
        }
    }

    //iterate through the columns and do stuff!
    columns.forEach(a -> {
        //do stuff to the column such as verify it was sorted, or sort it yourself etc
        System.out.println("column" + a.toString());
        a.forEach(b -> {
            //do stuff 
            LOG.info(b);
        });
    });

Ответы [ 4 ]

0 голосов
/ 11 января 2019

Если вы хотите, чтобы List<HtmlTableCell> представлял данные в данном столбце вашей HTML-таблицы, вам нужно использовать getCellAt , который принимает индекс строки и индекс столбца.

IntStream.range(0, numberOfColumns)
         .mapToObj(colIndex -> IntStream.range(0, numberOfRows)
             .mapToObj(rowIndex -> myTable.getCellAt(rowIndex, colIndex)).collect(toList())) 
         .collect(toList()); 

, где numberOfColumns должно быть заменено количеством столбцов в вашей таблице HTML, а numberOfRows должно быть заменено количеством строк в вашей таблице HTML.

Это даст List<List<HtmlTableCell>>, где каждый List<HtmlTableCell> - это все ячейки для каждого столбца.


Для полноты здесь вы можете отсортировать каждый List<HtmlTableCell>, то есть данные каждого столбца.

List<List<HtmlTableCell>> result = 
     IntStream.range(0, numberOfColumns)
              .mapToObj(colIndex -> IntStream.range(0, numberOfRows)
                     .mapToObj(rowIndex -> myTable.getCellAt(rowIndex, colIndex))
                     .sorted(Comparator.comparing(HtmlTableCell::asText))
                     .collect(toList())) 
              .collect(toList()); 

и зарегистрируйте его:

// concatenate each cell data of each column separated by a pipe and then separate each column data by a line separator.
String joined = result.stream()
      .map(l -> l.stream().map(HtmlTableCell::asText).collect(Collectors.joining("|")))
      .collect(Collectors.joining(System.lineSeparator()));
// log it! 
LOG.info(joined);

Обратите внимание, что если все, что вы делаете, это ведение журнала, то не стоит собирать промежуточное значение List<List<HtmlTableCell>>, вы можете получить требуемый результат как:

 String joined = IntStream.range(0, numberOfColumns)
                          .mapToObj(colIndex -> IntStream.range(0, numberOfRows)
                                .mapToObj(rowIndex -> myTable.getCellAt(rowIndex, colIndex).asText())
                                .sorted()
                                .collect(Collectors.joining("|")))
                        .collect(Collectors.joining(System.lineSeparator()));
LOG.info(joined);
0 голосов
/ 11 января 2019

Если вы хотите получить таблицу в виде списка списков (List<List<HtmlTableCell>>), это будет сделано

List<List<HtmlTableCell>> table = myTable.getRows().stream()
        .map(row -> row.getCells().stream().collect(Collectors.toList())
        .collect(Collectors.toList());

Или, если вам не понадобится List позже, вы можете пропустить сбор, чтобы просмотреть и выполнить код вместо

List<List<HtmlTableCell>> table = myTable.getRows().stream()
        .map(row -> row.getCells().stream().collect(Collectors.toList())
        .forEachOrdered(cellList -> System.out.println(cellList));
0 голосов
/ 11 января 2019

Вы можете получить его до List из List s:

List<List<HtmlTableCell>> columns = 
                          myTable.getRows()
                                 .stream()
                                 .map(row -> row.getCells()
                                                .stream()
                                                .collect(Collectors.toList())
                                 .collect(Collectors.toList());

А потом, когда вам нужно войти:

LOG.info(columns.stream()
                .flatMap(List::stream)                    
                .map(m -> m.asText())
                .sorted()         //Sort the list
                .collect(Collectors.joining("|")));
0 голосов
/ 11 января 2019

Вы можете сделать это как часть вашего объединения в виде единого потока:

webClient.getPage("http://localhost:8080/myUrl")
         .getHtmlElementById("myTable")
         .getRows()
         .stream()
         .map(row -> row.getCells().stream().findFirst().get().asText())
         .sort((o1, o2) -> o1.compareTo(o2)) // make alphabetical
         .collect(Collectors.joining("|"));
...