使用旧的循环,我想做的事情非常简单。
假设我有一个包含B列表的对象A.
public class A
{
public List<B> myListOfB;
}
在其他一些方法中,我有一个As的列表。基本上,我想要做的是合并所有我的B的列表中的所有元素。
例如,使用循环编写类似的内容非常容易:
public List<B> someMethod(List<A> myListOfAs)
{
List<B> toReturn = new ArrayList<A>();
for(A myA : myListOfAs)
{
toReturn.addAll(myA.myListOfB);
}
return toReturn;
}
但我想用Guava以更加有效的方式做到这一点。这个例子很简单,但是例如条件可能要复杂得多,因此使用函数式编程是有意义的。
我对番石榴很新。我已经开始使用它进行过滤和排序,但我很确定也可以使用它,但我无法弄清楚如何使用它。我找到了这个Combine multiple Collections into a single logical Collection?,但它并没有真正回答我的问题。
答案 0 :(得分:6)
您可以使用函数提取列表并使用concat来展平列表。这导致了Iterable。
List<A> input;
Function<A, List<B>> t = new Function<A, List<B>>() {
@Override public List<B> apply(A input) {
return input.myListOfB;
}
};
Iterable<B> transform = Iterables.concat(Iterables.transform(input, t));
如果需要,您可以创建一个列表:
ImmutableList<B> asList = ImmutableList.copyOf(transform);
//or
List<B> newArrayList = Lists.newArrayList(transform);
注意:通常,类的公共字段是静态的,不可变的或私有的。其他一切都会给你带来麻烦。
答案 1 :(得分:4)
如果您将A类实现为Iterable,则可以使用Iterables.concat()。
public class A
implements Iterable<B>
{
public List<B> myListOfB;
// from Iterable
public Iterator<B> iterator ()
{
return myListOfB.iterator();
}
}
然后:
List<A> listOfAs = ...;
Iterable<B> allBs = Iterables.concat(listOfAs);
将其放入另一个列表中:
List<B> listOfAllBs = Lists.newArrayList(allBs);
答案 2 :(得分:1)
这个怎么样?我只是粗暴地认为你的意思是:
public static void main(String[] args) {
A a1 = new A();
a1.bs = Lists.newArrayList(new B("1"), new B("2"), new B("3"));
A a2 = new A();
a2.bs = Lists.newArrayList(new B("a"), new B("b"), new B("c"));
A a3 = new A();
a3.bs = Lists.newArrayList(new B("!"), new B("@"), new B("#"));
List<A> as = Lists.newArrayList(a1, a2, a3);
List<B> lettersAndNumbers = method(as, new Predicate<A>() {
@Override
public boolean apply(A input) {
for (B s : input.bs) {
if (s.bVal.matches("^[a-zA-Z0-9]*$")) {
return true;
}
}
return false;
}
});
System.out.println("as : " + lettersAndNumbers);
}
static List<B> method(List<A> as, Predicate<A> pred) {
List<B> newbs = Lists.newArrayList();
Iterable<A> filtered = Iterables.filter(as, pred);
for (A a : filtered) {
newbs.addAll(a.bs);
}
return newbs;
}
class A {
List<B> bs;
@Override
public String toString() {
return "A{" + bs.toString() + "}";
}
}
class B {
String bVal;
B(String bVal) {
this.bVal = bVal;
}
@Override
public String toString() {
return "B{" + bVal + "}";
}
}