如何在JAVA中使用Stream来获取具有匹配值的对象?

huangapple go评论76阅读模式
英文:

How to use Stream in JAVA to get the object having a matching value?

问题

我有两个对象:

第一个对象:

public class ABC {

    private String a;
    private String b;
    private String c;
    private Boolean d;

    // 获取器和设置器
}

第二个对象:

public class DEF {

    private String a;
    private String b;
    private String c;

    // 获取器和设置器
}

有两个对象列表,分别是 ABC 对象的 List<ABC> listabc 和 DEF 对象的 List<DEF> listdef。我想要执行以下操作:

for (ABC abc : listabc) {
    if (abc.getD()) {
        for (DEF def : listdef) {
            if (abc.getA().equals(def.getA())) {
                abc.setB(def.getB());
                abc.setC(def.getC());
            }
        }
    }
}

我只是想看看是否有一种方法可以在 Stream 中实现这个操作,这样我就可以避免遍历列表并编写这段代码。

英文:

I have two objects:

First object:

public class ABC {

    private String a;
    private String b;
    private String c;
    private Boolean d;

    //getters and setters    
}

Second Object

public class DEF{

    private String a;
    private String b;
    private String c;

    //getters and setters    
}

There are two Lists of objects ABC and DEF - List<ABC> listabc and List<DEF> listdef. And I want to run the following operation:

for(ABC abc : listabc){
  if (abc.getD()) {
    for(DEF def : listdef){
      if(abc.getA().equals(def.getA()){
        abc.setB(def.getB());
        abc.setC(def.getC())
      }
    }
  }
}

I am just looking to see if there's a way to implement this operation in Stream so that I can avoid iterating through lists and writing this code.

答案1

得分: 2

这个解决方案应该产生与您的嵌套for循环相同的输出。

listabc.stream()
    .filter(ABC::getD)
    .forEach(abc -> listdef.stream()
        .filter(def -> def.getA().equals(abc.getA()))
        .findFirst().ifPresent(def -> {
            abc.setB(def.getB());
            abc.setC(def.getC());
        }));
英文:

This solution should give the same output as your nested for loop.

listabc.stream()
    .filter(ABC::getD)
    .forEach(abc -&gt; listdef.stream()
        .filter(def -&gt; def.getA().equals(abc.getA()))
        .findFirst().ifPresent(def -&gt; {
            abc.setB(def.getB());
            abc.setC(def.getC());
        }));

答案2

得分: 0

你可以用两个流来替换这两个嵌套的for循环:

List<ABC> listWithNewValues = listabc.stream().filter(ABC::getD)
        .map(abc -> {
            DEF matchingDef = listdef.stream().filter(def -> def.getA().equals(abc.getA())).findAny().get();
            abc.setB(matchingDef.getB());
            abc.setC(matchingDef.getC());
            return abc;
        })
        .collect(Collectors.toList());

你使用了两个列表,listabc和listdef。你在listabc上创建了一个流,通过boolean进行过滤,然后映射到新的值。在映射过程中,你在listdef上创建了一个流,找到匹配的元素。你可以将逻辑提取到一个方法中,以使代码更清晰。

英文:

You can replace the 2 nested for loops with two streams:

List&lt;ABC&gt; listWithNewValues = listabc.stream().filter(ABC::getD)
            .map(abc -&gt; {
                DEF matchingDef = listdef.stream().filter(def -&gt; def.getA().equals(abc.getA())).findAny().get();
                abc.setB(matchingDef.getB());
                abc.setC(matchingDef.getC());
                return abc;
            })
            .collect(Collectors.toList());

You use your 2 lists, listabc and listdef. You stream the listabc, you filter on the boolean and you map to the new values. During mapping you stream the listdef and find the matching element. You can extract the logic to a method to make it cleaner.

huangapple
  • 本文由 发表于 2020年5月19日 19:30:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/61889964.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定