集合导航和更新,(没有新集合)如何处理Java 8

时间:2016-01-11 10:57:52

标签: java-8

我有一个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;}

        }

1 个答案:

答案 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操作之一),所以你知道下次解决类似问题时从哪里开始。