如何在Java上使用而不使用嵌套for循环修改数组?

如何在Java上使用而不使用嵌套for循环修改数组?,java,groovy,collections,Java,Groovy,Collections,我使用的是Java 8和Groovy,不幸的是我不能使用lambdas,我有两个不同的对象列表,它们有一个共同的属性,在第一个列表中我得到了我需要的大部分数据,在第二个列表中我得到了共同的数据,我编写了一个for嵌套循环,以便用第二个列表中的共同属性更新第一个列表,我只是想知道是否有更好的方法来改进此代码: List<Object1> firstList = dao.something(); List<Object2> secondList = dao.s

我使用的是Java 8和Groovy,不幸的是我不能使用lambdas,我有两个不同的对象列表,它们有一个共同的属性,在第一个列表中我得到了我需要的大部分数据,在第二个列表中我得到了共同的数据,我编写了一个for嵌套循环,以便用第二个列表中的共同属性更新第一个列表,我只是想知道是否有更好的方法来改进此代码:

    List<Object1> firstList = dao.something();
    List<Object2> secondList = dao.something2();
    List<Object1> thirdList = new ArrayList<Object1>();

    for (Object1 obj1 : firstList){
        for(Object2 obj2 : secondList){
            if(obj1.getSomething().equals(obj2.getSomething())){
                    obj1.setAttribute(ojb2.getAttribute);
                    thirdList.add(obj1);
            }
        }
    }
List firstList=dao.something();
List secondList=dao.something2();
List thirdList=new ArrayList();
对于(Object1 obj1:firstList){
对于(Object2 obj2:secondList){
如果(obj1.getSomething().equals(obj2.getSomething())){
obj1.setAttribute(ojb2.getAttribute);
第三个列表添加(obj1);
}
}
}

任何帮助都会很有用,谢谢。

您可以使用Iterable的forEach方法遍历每个元素,在secondList中搜索并修改对象的内容

firstList.forEach(elem -> {
        V2 found = secondList.stream().filter(v1 -> v1.getId() == elem.getId()).findAny().orElse(null);               
        if(found != null) {
            elem.setAttribute(found);
        }
    });
或者您可以使用streams并将其映射到另一个列表中

 List<V1> thirdList = firstList.stream().map(elem -> { 
        V2 found = secondList.stream().filter(v1 -> v1.getId() == elem.getId()).findAny().orElse(null);               
        if(found != null) {
            elem.setAttribute(found);
        }
        return elem;
    }).collect(Collectors.toList());
List thirdList=firstList.stream().map(elem->{
V2 found=secondList.stream().filter(v1->v1.getId()==elem.getId()).findAny().orElse(null);
如果(找到!=null){
元素setAttribute(已找到);
}
返回元素;
}).collect(Collectors.toList());
如果你想比较两个列表,你总是需要迭代两次。
我希望这对您有所帮助。

您可以使用Iterable的forEach方法遍历每个元素,在secondList中搜索它,并修改对象的内容

firstList.forEach(elem -> {
        V2 found = secondList.stream().filter(v1 -> v1.getId() == elem.getId()).findAny().orElse(null);               
        if(found != null) {
            elem.setAttribute(found);
        }
    });
或者您可以使用streams并将其映射到另一个列表中

 List<V1> thirdList = firstList.stream().map(elem -> { 
        V2 found = secondList.stream().filter(v1 -> v1.getId() == elem.getId()).findAny().orElse(null);               
        if(found != null) {
            elem.setAttribute(found);
        }
        return elem;
    }).collect(Collectors.toList());
List thirdList=firstList.stream().map(elem->{
V2 found=secondList.stream().filter(v1->v1.getId()==elem.getId()).findAny().orElse(null);
如果(找到!=null){
元素setAttribute(已找到);
}
返回元素;
}).collect(Collectors.toList());
如果你想比较两个列表,你总是需要迭代两次。
我希望这对您有所帮助。

您可以使用Groovy的默认收集方法:

List thirdList = firstList.findResults{ obj1 ->
  def obj2attr = secondList.find{ obj1.something == it.something }?.attribute 
  if( obj2attr ){
    obj1.attribute = obj2attr
    obj1
  }else
    null
}

findResults()
过滤器
映射
收集
的便捷组合。您可以使用Groovy的默认收集方法:

List thirdList = firstList.findResults{ obj1 ->
  def obj2attr = secondList.find{ obj1.something == it.something }?.attribute 
  if( obj2attr ){
    obj1.attribute = obj2attr
    obj1
  }else
    null
}

findResults()
filter
map
collect

的便捷组合,也许使用map而不是list会有一些好处,比如
map
,其中
Id
getId()
返回的值的类型。如果对象具有唯一的Id,然后,您可以在
Map
中收集第二个列表。然后,对于第一个列表中的每个对象,获取id并从映射中获取所需的对象(如果它在映射中)。@chptr one感谢您提及唯一的id,但对象没有唯一的id,我更新了我的example@HarifVelarde在您的代码中,第一个列表中的每个对象将采用一个属性,该属性等于第二个列表中最后一个对象的属性,该对象找到了相同的公共属性。在第三个列表中,您将拥有第一个列表中相同对象的多个副本。是否正确?为了提高性能,我建议将list2转换为hashmap,如果它包含超过100个项目。在您的方法上也使用@CompileStatic。也许使用Map而不是list会有一些好处,比如
Map
,其中
Id
getId()
返回的值的类型。如果对象具有唯一的Id,那么您可以在
Map
中收集第二个列表。然后,对于第一个列表中的每个对象,获取id并从映射中获取所需的对象(如果它在映射中)。@chptr one感谢您提及唯一的id,但对象没有唯一的id,我更新了我的example@HarifVelarde在您的代码中,第一个列表中的每个对象将采用一个属性,该属性等于第二个列表中最后一个对象的属性,该对象找到了相同的公共属性。在第三个列表中,您将拥有第一个列表中相同对象的多个副本。是否正确?为了提高性能,我建议将list2转换为hashmap,如果它包含超过100个项目。在你的方法中也使用@CompileStatic。你的回答促使我找到一个很好的解决方案,谢谢你,我很乐意!至少它帮助了你你的回答驱使我找到一个很好的解决方案,谢谢你,我的荣幸!至少对你有帮助