Найдите каждый столбец в таблице в моем потоке java 8

Я использую 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);
        });
    });
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
0
2 428
4

Ответы 4

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

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("|"));

Если вы хотите получить таблицу в виде списка списков (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));

Вы можете собрать его на List из List:

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("|")));

Поскольку вы хотите, чтобы 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);

Другие вопросы по теме