关于使用Lambda 表达式,根据List中的对象的某个属性,求两个List的差集,结果报异常

一、需求逻辑:
1.先取出所有的车辆信息listWithoutDuplicates,并去重(该List数据最全,元素均为CarVo);
2.再从另一个表中取出车辆信息carForAdminList;(数据较少,元素均为CarForAdmin);
3.根据carForAdminList中的CarForAdmin车牌号是否存在于listWithoutDuplicates中为条件(即CarForAdmin.车牌号等于CarVo.车牌号),得出listWithoutDuplicates中多出的元素,并形成一个newTransferList
二、问题:
使用以下代码进行取差集:

List<CarVo> listWithoutDuplicates = CarDao.pageVoList(param);
List<CarForAdmin> carForAdminList = CarDao.pageList(param);
List<CarVo> newTransferList = listWithoutDuplicates.stream().filter(m -> !carForAdminList.stream().map(d -> d.getCarNum().replace(" ","")).collect(Collectors.toList()).contains(m.getCarNum().replace(" ",""))).collect(Collectors.toList());

运行后报错:
java.lang.ClassCastException: java.util.HashMap cannot be cast to CarForAdmin;

阅读 3.3k
1 个回答

Java Streaming API 提供了三个方法用于判断集合是否满足条件:

  • noneMatch
  • anyMatch
  • allMatch

下面是一个适合你的场景的实际例子,看完你就知道该怎么写了:

/**
 * 根据包含A,B两种类型的两个集合,从集合A中提取符合条件的子元素
 */
public class CollectionExtractor<A, B> {

    private final Collection<A> collectionA;

    private final Collection<B> collectionB;

    // 构造方法
    public CollectionExtractor(Collection<A> collectionA, Collection<B> collectionB) {
        this.collectionA = collectionA;
        this.collectionB = collectionB;
    }

    /**
     * 从集合A中提取所有不匹配集合B任何元素的元素
     *
     * @param matcher 匹配条件
     */
    public Stream<A> extractNoneMatch(BiFunction<A, B, Boolean> matcher) {
        return collectionA.stream().filter(
                a -> collectionB.stream().noneMatch(b -> matcher.apply(a, b))
        );
    }

    /**
     * 从集合A中提取所有至少匹配集合B中一个元素的元素
     *
     * @param matcher 匹配条件
     */
    public Stream<A> extractAnyMatch(BiFunction<A, B, Boolean> matcher) {
        return collectionA.stream().filter(
                a -> collectionB.stream().anyMatch(b -> matcher.apply(a, b))
        );
    }

    /**
     * 从集合A中提取所有匹配集合B全部元素的元素
     *
     * @param matcher 匹配条件
     */
    public Stream<A> extractAllMatch(BiFunction<A, B, Boolean> matcher) {
        return collectionA.stream().filter(
                a -> collectionB.stream().allMatch(b -> matcher.apply(a, b))
        );
    }

    ///////////////////////////////////////////////////////////////

    // 示例
    public static void main(String[] args) {

        List<String> numbers = Arrays.asList("1", "2", "3", "4", "5", "6", "7");
        List<Integer> factors = Arrays.asList(2, 3);

        // 查询所有 numbers 中不能被 factors 元素整除的数字
        Stream<String> result1 = new CollectionExtractor<>(numbers, factors)
                .extractNoneMatch((n, f) -> Integer.parseInt(n) % f == 0);

        // 输出 [1, 5, 7]
        System.out.println(result1.collect(Collectors.toList()));

        // 查询所有 numbers 中能被 factors 任意一个元素整除的数字
        Stream<String> result2 = new CollectionExtractor<>(numbers, factors)
                .extractAnyMatch((n, f) -> Integer.parseInt(n) % f == 0);

        // 输出 [2, 3, 4, 6]
        System.out.println(result2.collect(Collectors.toList()));

        // 查询所有 numbers 中能被 factors 所有元素整除的数字
        Stream<String> result3 = new CollectionExtractor<>(numbers, factors)
                .extractAllMatch((n, f) -> Integer.parseInt(n) % f == 0);

        // 输出 [6]
        System.out.println(result3.collect(Collectors.toList()));
    }
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题