在几个转换之间共享值?

时间:2013-04-01 17:06:42

标签: java design-patterns guava

想象一下,我有以下值列表:

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添加索引时,函数需要要知道,有a1 alraedy。

那么,做这样的事情是否有某种最佳实践?我目前的想法是创建一个以每个字母为键的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));

由于Map是一个对象并通过引用传递,我现在可以在转换之间共享计数器状态,对吧?反馈,更好的想法?在番石榴中是否有一些内置机制用于此类事物?

感谢任何提示!

2 个答案:

答案 0 :(得分:3)

使用Multiset替换HashMap,你可以按照@ Perception的建议将Multiset封装在Function本身并在应用函数时聚合数据。

答案 1 :(得分:3)

不要在这里使用transform,或者每次迭代时你的iterable都会有不同的值,并且通常表现得非常奇怪。 (在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));
}