2013-04-01 3 views
0

Представьте себе У меня есть следующий список значений:Доля значений между несколькими преобразованиями?

List<String> values = Lists.asList("a", "a", "b", "c"); 

Теперь я хочу, чтобы добавить индекс всех значений, так что один в конце концов с этим в качестве списка:

a1 a2 b1 c1 // imagine numbers as subscript 

Я хочу использовать FluentIterable и способ его transform для этого, так что-то вроде этого:

from(values).transform(addIndexFunction); 

проблема с этим в том, что addIndexFunction должен знать, как часто индекс был уже увеличен - подумайте о a2, при добавлении индекса к этому a функция должна знать, что есть alraedy a1.

Итак, есть ли какая-то лучшая практика для такого рода вещей? Моя текущая идея заключается в том, чтобы создать карту с каждой буквой в качестве ключа, так:

Map<String,Integer> counters = new HashMap<>(); 
// the following should be generated automatically, but for the sake of this example it's done manually... 
counters.put("a", 0); 
counters.put("b", 0); 
counters.put("c", 0); 

, а затем изменить свое преобразование вызова:

from(values).transform(addIndexFunction(counters)); 

Как Карта объекта и передается по ссылке, я теперь могу делиться встречным состоянием между преобразованиями, правильно? Обратная связь, лучшие идеи? Есть ли встроенный механизм для таких вещей в Гуаве?

Спасибо за подсказку!

+1

Я не думаю, что ваш идти, чтобы найти что-нибудь заранее построенный для это. Ваша идея звучит неплохо, хотя я бы инкапсулировал карту счетчика внутри самой функции и только создавал ключи для элементов, находящихся в самом списке (иначе, ленивая загрузка карты подсчета). – Perception

+0

Спасибо за отзыв и идею ленивой загрузки звучит неплохо, не подумал об этом :-) –

ответ

3

Используйте Multiset, чтобы заменить HashMap, и вы можете пойти, следуя предложению @ Perception о том, чтобы инкапсулировать Multiset в самой функции и агрегировать данные по мере применения функции.

+0

хорошая идея с мультимножеством, поэтому не нужно проверять, существует ли этот элемент или нет, когда вы пытаетесь выяснить count :-) Спасибо! –

3

Не используйте здесь transform, или ваш итеративный будет иметь разные значения каждый раз, когда вы перебираете его, и, как правило, ведут себя очень странно. (Это также несколько неодобрительно иметь состояние в Function.)

Вместо этого, сделать правильный for петлю с Multiset помощнике:

Multiset<String> counts = HashMultiset.create(); 
List<Subscript> result = Lists.newArrayList(); 
for (String value : values) { 
    int count = counts.add(value, 1); 
    result.add(new Subscript(value, count)); 
} 
Смежные вопросы