【问题标题】:Java-stream to filter list?Java-stream过滤列表?
【发布时间】:2021-03-16 18:31:13
【问题描述】:

如何在java 8流中使用过滤器过滤出复杂的对象列表。 假设我有这样的课程

public class InfoLite{
    private String right;
    List<Others> options;
    private String new;
}
//getter,setter and constructor
public class Others{    
    private String workId;
    private String work;
}
//getter,setter and constructor

我有一个与此类似的信息对象

List<InfoLite> info = new ArrayList<>();
List<Others> options = new ArrayList<>();
options.add(new Others(1,"game"))
options.add(new Others(2,"unit"))
options.add(new Others(3,"dest"))
List<Others> options2 = new ArrayList<>();
options.add(new Others(1,"console"))
options.add(new Others(2,"unit"))
List<Others> options3 = new ArrayList<>();
options.add(new Others(1,"zan"))
options.add(new Others(2,"zebvra"))
List<Others> options4 = new ArrayList<>();
options.add(new Others(1,"zan"))
options.add(new Others(2,"lon"))
options.add(new Others(3,"car"))
info.add(new Test("game,unit",options,"Florida"));
info.add(new Test("console",options2,"Florida"));
info.add(new Test("zebvra",options3,"Florida"));
info.add(new Test("lon",options4,"Florida"));

在这里我如何过滤info 列表,以便我可以获得这样的新列表

List<InfoLite> newInfo = new ArrayList<>();

List<Others> options = new ArrayList<>();
options.add(new Others(1,"game"))
options.add(new Others(2,"unit"))

List<Others> options2 = new ArrayList<>();
options.add(new Others(1,"console"))

List<Others> options3 = new ArrayList<>();
options.add(new Others(2,"zebvra"))

List<Others> options4 = new ArrayList<>();
options.add(new Others(2,"lon"))

info.add(new Test("game,unit",options,"Florida"));
info.add(new Test("console",options2,"Florida"));
info.add(new Test("zebvra",options3,"Florida"));
info.add(new Test("lon",options4,"Florida"));

这里Others 对象基本上被过滤了,即只过滤Others 列表中与info 中的right 匹配值的对象。如果info 中的right 是逗号分隔的,则拆分right 并签入每个Others 列表对象并返回值。

我尝试的到这里,但是我很困惑下一步该做什么。

info.stream()
            .filter(option -> Arrays.stream(option.getRight().split(",")).collect(Collectors.toList()).contains(option.getOptions().stream().filter(Others :: getWork))))``


【问题讨论】:

    标签: java java-stream


    【解决方案1】:

    假设,您打算打印与rightInfoLite 中的字符串之一匹配的所有Others 实例。

    如果是这种情况,下面的 sn-p 应该会有所帮助

    System.out.println(info.stream()
                           .flatMap(infoLite -> infoLite.getOptions()
                                                        .stream()
                                                        .filter(option -> Arrays.stream(infoLite.getRight()
                                                                                                .split(","))
                                                                                .collect(Collectors.toSet())
                                                                                .contains(option.getWork())))
                           .collect(Collectors.toSet()));
    

    输出:

    [Others{workId=1, work='console'}, Others{workId=2, work='zebvra'}, Others{workId=1, work='game'}, Others{workId=2, work='unit'}, Others{workId=2, work='lon'}]
    

    注意:我在请求程序中做了一些更改。

    • 在下面的sn-p
      List<Others> options2 = new ArrayList<>();
      options.add(new Others(1, "console"));
      
      应该是options2.add...
    • 假设TestInfoLite 的子类
    • Others 引入了equals()hashcode()
      @Override
      public boolean equals(Object o) {
          if (this == o) return true;
          if (o == null || getClass() != o.getClass()) return false;
          Others others = (Others) o;
          return workId == others.workId &&
                Objects.equals(work, others.work);
      }
      
      @Override
      public int hashCode() {
          return Objects.hash(workId, work);
      }
      

    更新 要检索完整的InfoList 实例,修改后的 sn-p 是

    info.forEach(infoLite -> {
        Set<String> rightSet = Arrays.stream(infoLite.getRight()
                                                     .split(","))
                                     .collect(Collectors.toSet());
        infoLite.getOptions()
                .removeIf(option -> !rightSet.contains(option.getWork()));
    });
    
    info.forEach(System.out::println);
    

    它产生以下输出

    InfoLite{right='game,unit', newString='Florida', options=[Others{workId=1, work='game'}, Others{workId=2, work='unit'}]}
    InfoLite{right='console', newString='Florida', options=[Others{workId=1, work='console'}]}
    InfoLite{right='zebvra', newString='Florida', options=[Others{workId=2, work='zebvra'}]}
    InfoLite{right='lon', newString='Florida', options=[Others{workId=2, work='lon'}]}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-08-11
      • 1970-01-01
      • 2021-07-25
      • 1970-01-01
      • 2017-06-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多