筛选列表wich属性不包含在另一个列表的属性中

时间:2019-02-13 22:39:16

标签: java list java-stream

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));

5 个答案:

答案 0 :(得分:2)

使用流API:

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

答案 1 :(得分: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}]

答案 2 :(得分:1)

使用Stream,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);

答案 3 :(得分:0)

使用noneMatch来避免现有的答案,只是现有答案的另一种变体:

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

答案 4 :(得分:-1)

您可以遍历两个列表并比较代码变量(据我了解,这是您要比较的唯一条件?):

SELECT * 
FROM `apt` 
LEFT JOIN `build_apt` 
    ON  `build_apt`.`id_apt` = `apt`.`id_apt` 
    AND `build_apt`.`id_build` = 1 
    AND `apt`.`id_typeapt` in (1, 2, 3, 4, 5)