在我的Java 8流中找到表中的每一列

时间:2019-01-10 20:58:03

标签: java java-stream htmlunit

我正在使用HtmlUnit来获取HtmlTable。我试图获取每列的单元格列表。

到目前为止,在我尝试过的代码中,我可以找到第一列。如何遍历每一列并在其中运行一些代码?

我想确保它们都按字母顺序排序,但是我只需要弄清楚放置代码的位置。

编辑:我找到了答案。我想我把这个问题说错了。我需要获取每一列并将其放入自己的收藏集中。在原始示例中,我仅显示了column1。但是我需要EACH列(基于每行中有多少个单元格)。以下是一些有效的代码。但是它可能可以进行更好的优化。

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 :(得分:2)

您可以将其作为单个流作为连接的一部分来完成:

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

答案 1 :(得分:2)

您可以将其收集到List的{​​{1}}中:

List

然后在您需要登录时:

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

答案 2 :(得分:1)

如果您想以列表列表的形式获取表格(dict

blah.someDict

或者,如果以后不再需要'a',则可以跳过收集以列出并执行代码

List<List<HtmlTableCell>>

答案 3 :(得分:1)

如果您想用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);