ImmutableTableFactory { public static <R, C, V, M, N, W> ImmutableTable<M, N, W> create( Table<R, C, V> baseTable, Function<? super R, ? extends M> rowMapper, Function<? super C, ? extends N> columnMapper, Function<? super V, ? extends W> valueMapper) { ImmutableTable.Builder<M, N, W> mappedTableBuilder = ImmutableTable.builder(); TableUtils.forEach(baseTable, (r, c, v) -> mappedTableBuilder.put( rowMapper.apply(r), columnMapper.apply(c), valueMapper.apply(v))); try { return mappedTableBuilder.build(); } catch (IllegalArgumentException e) { throw new IllegalArgumentException("Multiple input cells mapped to the same ouput cell", e); } }  static ImmutableTable<M, N, W> create(
            Table<R, C, V> baseTable,
            Function<? super R, ? extends M> rowMapper,
            Function<? super C, ? extends N> columnMapper,
            Function<? super V, ? extends W> valueMapper); static ImmutableTable<R, C, W> create(
            Table<? extends R, ? extends C, V> baseTable,
            Function<? super V, ? extends W> valueMapper); static ImmutableTable<R, C, V> create(
            Table<? extends R, ? extends C, ?> baseTable,
            BiFunction<? super R, ? super C, ? extends V> newValueCalculator); static ImmutableTable<R, C, V> createWithRows(
            Map<? extends C, ? extends V> baseMap,
            Collection<? extends R> rows); static ImmutableTable<R, C, V> createWithColumns(
            Map<? extends R, ? extends V> baseMap,
            Collection<? extends C> columns); static ImmutableTable<R, C, V> create(
            Collection<? extends R> rowKeys,
            Collection<? extends C> columnKeys,
            BiFunction<? super R, ? super C, ? extends V> valueCreator); static ImmutableTable<R, C, V> create(
            Collection<? extends R> rowKeys,
            Collection<? extends C> columnKeys,
            Supplier<? extends V> valueSupplier);  }
@Test void testCreateFromTableAndMapper() { ImmutableTable<String, Integer, String> outputTable = ImmutableTableFactory.create( nonFullTable, value -> String.valueOf(value + 10)); Assertions.assertEquals(3, outputTable.size()); Assertions.assertEquals("10.0", outputTable.get(FIRST_ROW, 0)); Assertions.assertEquals("10.1", outputTable.get(FIRST_ROW, 1)); Assertions.assertEquals("11.0", outputTable.get(SECOND_ROW, 0)); }
@Test void testCreateFromTableCells() { ImmutableTable<String, Integer, String> outputTable = ImmutableTableFactory.create( nonFullTable, (row, column) -> row + column); Assertions.assertEquals(3, outputTable.size()); Assertions.assertEquals(FIRST_ROW + "0", outputTable.get(FIRST_ROW, 0)); Assertions.assertEquals(FIRST_ROW + "1", outputTable.get(FIRST_ROW, 1)); Assertions.assertEquals(SECOND_ROW + "0", outputTable.get(SECOND_ROW, 0)); }
@Test void testCreateFromOtherTableFullMapping() { Table<Integer, String, Integer> outputTable = ImmutableTableFactory.create( nonFullTable, s -> Integer.valueOf(s.substring(4)), String::valueOf, Double::intValue); Assertions.assertEquals(3, outputTable.size()); Assertions.assertEquals( 0, (int) outputTable.get(0, "0")); Assertions.assertEquals(0, (int) outputTable.get(0, "1")); Assertions.assertEquals(1, (int) outputTable.get(1, "0")); }