【问题标题】:Collections Navigate and update, (no new collections) How to do with Java 8集合导航和更新,(没有新集合)如何使用 Java 8
【发布时间】:2016-01-11 10:57:51
【问题描述】:

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

        }

【问题讨论】:

  • 所以你的代码现在不起作用了?问题是什么?还请提供可编译的代码。目前它充满了编译错误。你真的用 == 比较字符串吗?
  • b.setAObjs(a); 接受一个 List 但你用一个对象设置它。

标签: java-8


【解决方案1】:

即使在 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 表达式、流收集操作和 Map 接口的新 default 操作之一),所以您知道下次解决类似问题时从哪里开始。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-18
    • 1970-01-01
    • 2019-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-25
    • 2011-04-27
    相关资源
    最近更新 更多