Coverage Summary for Class: TableCollectors (com.google.common.collect)

Class Method, % Line, %
TableCollectors 0% (0/14) 0% (0/43)
TableCollectors$ImmutableTableCollectorState 0% (0/5) 0% (0/15)
TableCollectors$MutableCell 0% (0/5) 0% (0/9)
Total 0% (0/24) 0% (0/67)


1 /* 2  * Copyright (C) 2009 The Guava Authors 3  * 4  * Licensed under the Apache License, Version 2.0 (the "License"); 5  * you may not use this file except in compliance with the License. 6  * You may obtain a copy of the License at 7  * 8  * http://www.apache.org/licenses/LICENSE-2.0 9  * 10  * Unless required by applicable law or agreed to in writing, software 11  * distributed under the License is distributed on an "AS IS" BASIS, 12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13  * See the License for the specific language governing permissions and 14  * limitations under the License. 15  */ 16  17 package com.google.common.collect; 18  19 import static com.google.common.base.Preconditions.checkNotNull; 20  21 import com.google.common.annotations.GwtCompatible; 22 import com.google.common.collect.Tables.AbstractCell; 23 import java.util.ArrayList; 24 import java.util.List; 25 import java.util.function.BinaryOperator; 26 import java.util.function.Function; 27 import java.util.function.Supplier; 28 import java.util.stream.Collector; 29  30 /** Collectors utilities for {@code common.collect.Table} internals. */ 31 @GwtCompatible 32 final class TableCollectors { 33  34  static <T, R, C, V> Collector<T, ?, ImmutableTable<R, C, V>> toImmutableTable( 35  Function<? super T, ? extends R> rowFunction, 36  Function<? super T, ? extends C> columnFunction, 37  Function<? super T, ? extends V> valueFunction) { 38  checkNotNull(rowFunction, "rowFunction"); 39  checkNotNull(columnFunction, "columnFunction"); 40  checkNotNull(valueFunction, "valueFunction"); 41  return Collector.of( 42  (Supplier<ImmutableTable.Builder<R, C, V>>) ImmutableTable.Builder::new, 43  (builder, t) -> 44  builder.put(rowFunction.apply(t), columnFunction.apply(t), valueFunction.apply(t)), 45  ImmutableTable.Builder::combine, 46  ImmutableTable.Builder::build); 47  } 48  49  static <T, R, C, V> Collector<T, ?, ImmutableTable<R, C, V>> toImmutableTable( 50  Function<? super T, ? extends R> rowFunction, 51  Function<? super T, ? extends C> columnFunction, 52  Function<? super T, ? extends V> valueFunction, 53  BinaryOperator<V> mergeFunction) { 54  55  checkNotNull(rowFunction, "rowFunction"); 56  checkNotNull(columnFunction, "columnFunction"); 57  checkNotNull(valueFunction, "valueFunction"); 58  checkNotNull(mergeFunction, "mergeFunction"); 59  60  /* 61  * No mutable Table exactly matches the insertion order behavior of ImmutableTable.Builder, but 62  * the Builder can't efficiently support merging of duplicate values. Getting around this 63  * requires some work. 64  */ 65  66  return Collector.of( 67  () -> new ImmutableTableCollectorState<R, C, V>() 68  /* GWT isn't currently playing nicely with constructor references? */ , 69  (state, input) -> 70  state.put( 71  rowFunction.apply(input), 72  columnFunction.apply(input), 73  valueFunction.apply(input), 74  mergeFunction), 75  (s1, s2) -> s1.combine(s2, mergeFunction), 76  state -> state.toTable()); 77  } 78  79  static <T, R, C, V, I extends Table<R, C, V>> Collector<T, ?, I> toTable( 80  java.util.function.Function<? super T, ? extends R> rowFunction, 81  java.util.function.Function<? super T, ? extends C> columnFunction, 82  java.util.function.Function<? super T, ? extends V> valueFunction, 83  java.util.function.Supplier<I> tableSupplier) { 84  return toTable( 85  rowFunction, 86  columnFunction, 87  valueFunction, 88  (v1, v2) -> { 89  throw new IllegalStateException("Conflicting values " + v1 + " and " + v2); 90  }, 91  tableSupplier); 92  } 93  94  static <T, R, C, V, I extends Table<R, C, V>> Collector<T, ?, I> toTable( 95  java.util.function.Function<? super T, ? extends R> rowFunction, 96  java.util.function.Function<? super T, ? extends C> columnFunction, 97  java.util.function.Function<? super T, ? extends V> valueFunction, 98  BinaryOperator<V> mergeFunction, 99  java.util.function.Supplier<I> tableSupplier) { 100  checkNotNull(rowFunction); 101  checkNotNull(columnFunction); 102  checkNotNull(valueFunction); 103  checkNotNull(mergeFunction); 104  checkNotNull(tableSupplier); 105  return Collector.of( 106  tableSupplier, 107  (table, input) -> 108  mergeTables( 109  table, 110  rowFunction.apply(input), 111  columnFunction.apply(input), 112  valueFunction.apply(input), 113  mergeFunction), 114  (table1, table2) -> { 115  for (Table.Cell<R, C, V> cell2 : table2.cellSet()) { 116  mergeTables( 117  table1, cell2.getRowKey(), cell2.getColumnKey(), cell2.getValue(), mergeFunction); 118  } 119  return table1; 120  }); 121  } 122  123  private static final class ImmutableTableCollectorState<R, C, V> { 124  final List<MutableCell<R, C, V>> insertionOrder = new ArrayList<>(); 125  final Table<R, C, MutableCell<R, C, V>> table = HashBasedTable.create(); 126  127  void put(R row, C column, V value, BinaryOperator<V> merger) { 128  MutableCell<R, C, V> oldCell = table.get(row, column); 129  if (oldCell == null) { 130  MutableCell<R, C, V> cell = new MutableCell<>(row, column, value); 131  insertionOrder.add(cell); 132  table.put(row, column, cell); 133  } else { 134  oldCell.merge(value, merger); 135  } 136  } 137  138  ImmutableTableCollectorState<R, C, V> combine( 139  ImmutableTableCollectorState<R, C, V> other, BinaryOperator<V> merger) { 140  for (MutableCell<R, C, V> cell : other.insertionOrder) { 141  put(cell.getRowKey(), cell.getColumnKey(), cell.getValue(), merger); 142  } 143  return this; 144  } 145  146  ImmutableTable<R, C, V> toTable() { 147  return ImmutableTable.copyOf(insertionOrder); 148  } 149  } 150  151  private static final class MutableCell<R, C, V> extends AbstractCell<R, C, V> { 152  private final R row; 153  private final C column; 154  private V value; 155  156  MutableCell(R row, C column, V value) { 157  this.row = checkNotNull(row, "row"); 158  this.column = checkNotNull(column, "column"); 159  this.value = checkNotNull(value, "value"); 160  } 161  162  @Override 163  public R getRowKey() { 164  return row; 165  } 166  167  @Override 168  public C getColumnKey() { 169  return column; 170  } 171  172  @Override 173  public V getValue() { 174  return value; 175  } 176  177  void merge(V value, BinaryOperator<V> mergeFunction) { 178  checkNotNull(value, "value"); 179  this.value = checkNotNull(mergeFunction.apply(this.value, value), "mergeFunction.apply"); 180  } 181  } 182  183  private static <R, C, V> void mergeTables( 184  Table<R, C, V> table, R row, C column, V value, BinaryOperator<V> mergeFunction) { 185  checkNotNull(value); 186  V oldValue = table.get(row, column); 187  if (oldValue == null) { 188  table.put(row, column, value); 189  } else { 190  V newValue = mergeFunction.apply(oldValue, value); 191  if (newValue == null) { 192  table.remove(row, column); 193  } else { 194  table.put(row, column, newValue); 195  } 196  } 197  } 198  199  private TableCollectors() {} 200 }