作者:和谐家于社会 | 来源:互联网 | 2023-10-13 09:45
我有一个包含两个字符串属性的对象列表.
public class A {
public String a;
public String b;
}
我想检索两个包含属性a和一个b的集合.
这些方法的天真之处在于:
List list = ....
Set listofa = new HashSet<>();
Set listofb = new HashSet<>();
for (A item : list) {
if (item.a != null)
listofa.add(item.a);
if (item.b != null)
listofb.add(item.b);
}
试图以一种功能性的方式在番石榴中完成,我最终得到了这种方法:
Function getAFromList = new Function<>() {
@Nullable
@Override
public String apply(@Nullable A input) {
return input.a;
}
};
Function getBFromList = Function<>() {
@Nullable
@Override
public String apply(@Nullable A input) {
return input.b;
}
};
FluentIterable iterables = FluentIterable.from(list);
Set listofAs = ImmutableSet.copyOf(iterables.transform(getAFromList).filter(Predicates.notNull()));
Set listofBs = ImmutableSet.copyOf(iterables.transform(getBFromList).filter(Predicates.notNull()));
但是,这样一来,我将在列表上进行两次迭代.
有什么方法可以避免重复两次或多次?
总的来说,如何以一种实用的方式解决这些用例(不仅在guava / java中)?
解决方法:
首先,您要进行优化-但是,如果性能至关重要,请在番石榴上使用常规的Java方法(即您的第一种方法).参见here.
我想因为您想要两个结果,所以在某个时候您将需要迭代两次(除非您传入要填充的集合之一,但这绝对不是fp方法,因为它不是纯函数).
但是,如果迭代的成本足以需要优化,则可以将其迭代一次到中间结构:
a_b_pairs = transformToJustAB(input) //single expensive iteration
list_of_a = transformA(a_b_pairs) //multiple cheaper iterations
list_of_b = transformB(a_b_pairs)