Java tutorial
/* * Copyright 2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package io.github.carlomicieli.footballdb.starter.pages; import org.apache.commons.lang3.tuple.ImmutablePair; import java.util.*; import java.util.function.Function; import java.util.function.IntFunction; import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; import static java.util.stream.Collectors.toMap; /** * It represents an immutable Table, with an optional header. * * @author Carlo Micieli */ public class Table { private final List<String> headers; private final List<Row> rows; private final ImmutablePair<Integer, Integer> size; protected Table(TableBuilder tb) { this.size = ImmutablePair.of(tb.size.getKey(), tb.size.getValue()); this.headers = Collections.unmodifiableList(tb.columnHeaders); this.rows = tb.values.stream().map(r -> Row.of(r, headers)).collect(Collectors.toList()); } /** * Returns a new <em>TableBuilder</em> to build tables * * @return a new table builder */ public static TableBuilder builder() { return new TableBuilder(); } /** * Returns the number of table rows. * * @return the rows count */ public int columnsCount() { return size.getRight(); } /** * Returns the number of rows in the table. * * @return the rows count */ public int rowsCount() { return size.getLeft(); } /** * Returns the table size. * * @return the table size */ public ImmutablePair<Integer, Integer> size() { return size; } /** * Returns the n-th row in the table, or <em>Optional.empty()</em> if the * column is not present. * * @param index the row number (starting from 1) * @return a row */ public Optional<Row> row(int index) { if (index > size.getLeft()) { return Optional.empty(); } return Optional.ofNullable(rows.get(index - 1)); } /** * Returns the List of extractValues for the n-th row in the table. * @param index the row number (starting from 1) * @return */ public Optional<List<String>> rowValues(int index) { return row(index).map(r -> r.values); } /** * Returns the table header. * * @return the header */ public List<String> header() { return headers; } /** * Returns the stream for the table rows. * * @return the rows */ public Stream<Row> rowsStream() { return rows.stream(); } public Map<String, String> valuesForRow(int n) { if (tableWithoutHeader()) return Collections.emptyMap(); return rowValues(n).map(cells -> { Map<String, String> m = IntStream.range(0, columnsCount()).mapToObj(bindHeaderWithValue(cells)) .collect(toMap(p -> p.getKey(), p -> p.getValue())); return m; }).orElse(null); } @Override public String toString() { return "Table(" + headersToString() + rowsToString() + ")"; } private String rowsToString() { return rowsStream().map(Row::toString).collect(Collectors.joining(", ")); } private String headersToString() { if (tableWithoutHeader()) return ""; return "Header(" + headers.stream().collect(Collectors.joining(", ")) + "), "; } private IntFunction<ImmutablePair<String, String>> bindHeaderWithValue(List<String> cells) { return index -> ImmutablePair.of(headers.get(index), cells.get(index)); } private boolean tableWithoutHeader() { return headers.size() == 0; } public Stream<Row> filter(Predicate<Row> predicate) { return rowsStream().filter(predicate); } public Stream<Row> map(Function<Row, Row> mapper) { return rowsStream().map(mapper); } public static class Row { private final List<String> values; private final List<String> header; private Row(List<String> values, List<String> header) { this.values = values; this.header = header; } public static Row of(List<String> values, List<String> header) { return new Row(values, header); } public String value(int column) { return get(column - 1); } public String value(String columnName) { if (header.size() == 0) throw new UnsupportedOperationException("Table without header"); int index = header.indexOf(columnName); if (index != -1) { return get(index); } return ""; } public Row subset(String... columns) { List<String> values = Stream.of(columns).map(this::value).collect(Collectors.toList()); return new Row(values, Arrays.asList(columns)); } @Override public String toString() { return "Row(" + values.stream().collect(Collectors.joining(", ")) + ")"; } private String get(int index) { return values.get(index); } } }