【问题标题】:Filtering List which property is not included in property of another List过滤列表哪个属性不包含在另一个列表的属性中
【发布时间】:2019-02-13 22:39:15
【问题描述】:
public class Bill {
    private Long code;

    public Bill(Long code) {
        this.code = code;
    }
    // setters and Getters
}

class Detail {
    private BillId billId;

    public Detail(BillId billId) {
        this.billId = billId;
    }
    // setters and Getters

}

class BillId {
    private Long number;
    private Long code;

    public BillId(Long number, Long code) {
        this.number = number;
        this.code = code;
    }
    // setters and Getters
}

现在我有

List<Bill> listBill = new ArrayList<>();
listBill.add(new Bill(1L));
listBill.add(new Bill(2L));
listBill.add(new Bill(3L));
listBill.add(new Bill(4L));
listBill.add(new Bill(5L));
listBill.add(new Bill(6L));


List<Detail> listDetail = new ArrayList<>();
listDetail.add(new Detail(new BillId(1000L, 10L)));
listDetail.add(new Detail(new BillId(1000L, 2L)));
listDetail.add(new Detail(new BillId(2000L, 30L)));
listDetail.add(new Detail(new BillId(2000L, 4L)));
listDetail.add(new Detail(new BillId(3000L, 50L)));
listDetail.add(new Detail(new BillId(3000L, 6L)));

现在我需要一个new ListlistBill 获取项目,其中一些项目与listDetail 中的一些项目不匹配

detail.getBillId ().getCode() not match with bill.getCode()

预期列表对不起新的!

newListBill.add(new Bill(1L)); 
newListBill.add(new Bill(3L));
newListBill.add(new Bill(5L));

【问题讨论】:

  • 请修复void BillIdList&lt;Detail&gt; listDetail
  • @tsolakp 谢谢!

标签: java list java-stream


【解决方案1】:

使用流 API:

listBill.stream()
.filter( b -> !listDetail.stream()
     .anyMatch( d -> d.getBillId().getCode() == b.getCode() ) )
.collect( Collectors.toList() );

【讨论】:

  • 对不起。我使用了您的旧示例代码。查看更新后的答案。
  • 你可以用noneMatch代替! anyMatch
【解决方案2】:

O(nlogn) 复杂度有更优化的解决方案。首先从详细信息中获取代码列表:

List<Long> codes = listDetail.stream()
            .map(detail -> detail.getBillId().getCode())
            .sorted()
            .collect(Collectors.toList());

现在使用二分搜索进行过滤(codes 已经排序):

List<Bill> collect = listBill.stream()
            .filter(bill -> Collections.binarySearch(codes, bill.getCode()) < 0)
            .collect(Collectors.toList());

System.out.println(collect);      // [Bill{code=1}, Bill{code=3}, Bill{code=5}]

【讨论】:

    【解决方案3】:

    使用流,Java 8

        List<Bill> substractListBill = listBill.stream().filter(bill -> !listDetail.stream()
                .map(Detail::getBillId)
                .map(BillId::getCode)
                .anyMatch(code ->  Objects.equals(code, bill.getCode())))
                .collect(Collectors.toList());
        System.out.println(substractListBill);
    

    【讨论】:

      【解决方案4】:

      使用noneMatch 是现有答案的另一种变体,以避免显式否定:

      List<Bill>  output = listBill.stream()
              .filter( b -> listDetail.stream()
                    .noneMatch(d -> d.getBillId().getCode().equals(b.getCode()))) // change here
              .collect(toList());
      

      【讨论】:

      【解决方案5】:

      您可以遍历两个列表并比较代码变量(据我所知,这是您要比较的唯一标准?):

          ArrayList<Bill> result = new ArrayList<>();
          for(Bill bill: listBill) {
             for(Detail detail : listDetail) {
                if(bill.getCode() == detail.getBillId().getCode() {
                      result.add(bill);
              }
            }
      }
      

      【讨论】:

      • 条件是,如果没有找到!
      猜你喜欢
      • 1970-01-01
      • 2021-08-22
      • 2022-01-25
      • 2021-08-10
      • 1970-01-01
      • 1970-01-01
      • 2016-08-24
      • 2019-05-05
      • 1970-01-01
      相关资源
      最近更新 更多