2013-04-01 26 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時,該函數需要知道的是,已存在aldy的一個a1

那麼,有沒有某種最佳做法做這樣的事情?我現在的想法是創建一個Map,每個字母的關鍵,所以:

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

與multiset好主意,所以一個人不必檢查項目是否存在或試圖找出計數:-)謝謝! –

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)); 
}