2016-08-23 7 views
1

Список процессов с помощью метода, который возвращает ImmutableTable<R,C,V>. Например, ImmutableTable<Integer,String,Boolean> process(String item) { /*...*/}.Java 8 collector для Guava ImmutableTable с использованием HashBasedTable как аккумулятора дает IllegalAccessError

Соберите результат i.e, слейте все результаты (отдельная таблица может содержать дубликаты) и вернуть ImmutableTable.

Моя текущая реализация работает, когда нет дубликатов:

final ImmutableTable<Integer, String, Boolean> result = 
      itemsToProcess.parallelStream() 
        .map(item -> 
          ProcessorInstanceProvider.get() 
            .buildTable(item)) 
        .collect(toImmutableTable()); 

public static <R, C, V> Collector<ImmutableTable<R, C, V>,  
ImmutableTable.Builder<R, C, V>, ImmutableTable<R, C, V>> 
toImmutableTable() { 
    return Collector.of(
      ImmutableTable.Builder<R, C, V>::new, 
      ImmutableTable.Builder<R, C, V>::putAll, 
      (
        a, 
        b) -> a.putAll(b.build()), 
      ImmutableTable.Builder::build); 
    } 

Но она не во время сбора ImmutableTable, как есть повторяющиеся записи строк столбцов и, следовательно, построить не удается.

Как я могу предотвратить сбой сборки? Как я могу использовать HashBaseTable, который будет работать с дубликатами. Что-то вроде T - ImmutableTable, A - HashBasedTable и R - ImmutableTable с минимальным использованием памяти?

Пробовал с:

final HashBasedTable<Integer, String, Boolean> result = 
      listOfItems.parallelStream() 
      .map(item ->        
ProcessorInstanceProvider.get() 
        .build(item)) 
        .collect(
          Collector.of(
            HashBasedTable::create, 
            HashBasedTable::putAll, 
            (a, b) -> { 
             a.putAll(b); 
             return a; 
            })); 

Но получить ошибки во время выполнения:

Caused by: java.lang.IllegalAccessError: tried to access class com.google.common.collect.AbstractTable 

для HashTable::putAll.

Как мы можем использовать HashBasedTable в качестве накопителя для сбора ImmutablesTable, а HashBasedTable переопределяет существующую запись с последними один и не терпит неудачу, если мы попытаемся поставить повторяющиеся записи, и вернуть агрегированный непреложную таблицу.

+3

'IllegalAccessError' выглядит как ошибка компилятора. Попробуйте заменить ссылки на методы эквивалентными лямбда-выражениями. Я смутно помню, что видел подобную проблему. – Holger

+0

Что вы хотите делать с дубликатами? – shmosel

+0

Для дубликатов я просто хочу переопределить его с помощью последней записи, которую делает HashBasedTable. – sidss

ответ

1

Замененный метод ссылки с выражением лямбда и это сработало.

ImmutableTable.copyOf(itemList.parallelStream() 
        .map(item -> 
          ProcessorInstanceProvider.get() 
          .build(item)) 
        .collect(() -> HashBasedTable.create(), 
          (a, b) -> a.putAll(b), 
          (a, b) -> a.putAll(b)) 
        );