我有一个aList和一个bList,两个都有一个常用的字段,这是我匹配两个列表的引用。 一旦两个列表引用匹配,我想用aList更新bList对象。 常规方法如下,如何在java 8中实现相同的目标?
// How to save below piece of two iterations (along with compare* and update*)
// using java 8 ?
// Stream filter will return new Collection but not update same (bList)
for (A a : aList)
{
for(B b: bList )
{
// compare*
if(a.getStrObj.equalsIgnoreCase(b.getStrObj))
{
// update*
// assume aObjs is initialized
b.getAObjs().add(a);
}
}
}
// Reference for Objects declaration
List<A> aList;
class A {
String strObj;
public String getStrObj()
{ return strObj; }
}
List<B> bList;
class B {
String strObj;
List<A> aObjs;
public getStrObj()
{ return strObj; }
public setAObjs(List<A> aObjs)
{ this.aObjs= aObjs; }
public getAObjs()
{ return this.aObjs;}
}
答案 0 :(得分:0)
你的嵌套循环不是最好的方法,甚至在Java 8之前(除非你能证明列表总是很小)。您应该使用临时Map
快速查找其中一个列表,以避免执行m×n
操作(字符串比较)。
使用Java 8实现这一目标的一种方法是
Map<String, List<A>> m=aList.stream().collect(Collectors.groupingBy(A::getStrObj));
bList.forEach(b -> b.getAObjs()
.addAll(m.getOrDefault(b.getStrObj(), Collections.emptyList())));
我们正在执行m+n
次操作而不是m×n
次操作,这些操作随着列表大小的增加而扩展得更好。
您可以使用Java 8之前的构造创建一个等效的实现,即两个独立的循环而不是两个嵌套循环,结果代码不一定比上面的Java 8代码差。
尽管如此,上面的代码可能会向您介绍一些最重要的功能(方法引用,lambda表达式,流收集操作以及default
接口的新Map
操作之一),所以你知道下次解决类似问题时从哪里开始。