两个 list<bean> 使用java8根据某几个属性去重复

1:需求

定时从其他微服务同步数据,保存到本地数据库。数据量大,如果每条数据每次都更新,则比较慢。因此需要“远程拉取数据list(A)”与"本地数据查询的list(B)"依据某些字段比较,然后获取A=B、A>B、B=A、B>A (谁在前stream是以谁为基础)

2:数据准备

两个对象+两个list。。模拟从远程获取的数据+本地库查找的数据
@Data
public class Dish {
    private String name;    //菜的名称
    private Boolean vegetaian;  //是否为素
    private Integer calories;   //卡路里
    private Type type;      //类型(肉 鱼 其他)
    public Dish() { }
    public Dish(String name, Boolean vegetaian, Integer calories, Type type) {
        this.name = name;
        this.vegetaian = vegetaian;
        this.calories = calories;
        this.type = type;
    }
    public enum Type {MEAT, FISH, OTHER} //肉 鱼 其他
}

@Data
public class UmDish {

    private String umname;    //菜的名称
    private Boolean umvegetaian;  //是否为素
    private Integer umcalories;   //卡路里
    private UmType umtype;      //类型(肉 鱼 其他)
    public UmDish() {
    }
    public UmDish(String umname, Boolean umvegetaian, Integer umcalories, UmType umtype) {
        this.umname = umname;
        this.umvegetaian = umvegetaian;
        this.umcalories = umcalories;
        this.umtype = umtype;
    }
    public enum UmType {MEAT, FISH, OTHER} //肉 鱼 其他
}
    //数据准备
    public static List<UmDish> getUmDish1List() {
        return Arrays.asList(
                new UmDish("pork", false, 800, UmDish.UmType.MEAT),
                new UmDish("beef-1", false, 700, UmDish.UmType.MEAT),
                new UmDish("chicken-1", false, 400, UmDish.UmType.MEAT),
                new UmDish("french fries", true, 530, UmDish.UmType.OTHER),
                new UmDish("rice", true, 350, UmDish.UmType.OTHER),
                new UmDish("season fruit", true, 120, UmDish.UmType.OTHER),
                new UmDish("pizza", true, 550, UmDish.UmType.OTHER),
                new UmDish("prawns", false, 300, UmDish.UmType.FISH),
                new UmDish("salmon", false, 450, UmDish.UmType.FISH)
        );
    }
    //数据准备
    public static List<Dish> getDish1List() {
        return Arrays.asList(
                new Dish("pork", false, 800, Dish.Type.MEAT),
                new Dish("pork-1", false, 800, Dish.Type.MEAT),
                new Dish("beef", false, 700, Dish.Type.MEAT),
                new Dish("chicken", false, 400, Dish.Type.MEAT),
                new Dish("french fries", true, 530, Dish.Type.OTHER),
                new Dish("rice", true, 350, Dish.Type.OTHER),
                new Dish("season fruit", true, 120, Dish.Type.OTHER),
                new Dish("pizza", true, 550, Dish.Type.OTHER),
                new Dish("prawns", false, 300, Dish.Type.FISH),
                new Dish("salmon", false, 450, Dish.Type.FISH)
        );
    }

3:解决方案

方案1:for循环方法

略。。。。。。
缺点:如果好多种list需要比较,则要针对写不同的比较策略,代码长,不易阅读,而且修改不灵活(比如:获取A=B、A!=B、A>B、A<B 是非常麻烦的)

方案2:封装通用方法

方法:

    /**
     * 过滤两个list<Bean>数据的策略(bean对象可以不同)
     *
     * @param otherList     被比较的List<bean>
     * @param otherFunction 被比较的Function(目的是为了组装key)
     * @param thisFunction  调用此方法方的Function(目的是为了组装key)
     * @return
     */
    public static <E, M, V> Predicate<E> distinctByOtherList(List<M> otherList, Function<M, V> otherFunction, Function<E, V> thisFunction) {
        Set<V> otherKeySet = otherList.stream().map(otherFunction).collect(Collectors.toSet());
        return e -> Boolean.TRUE.equals(otherKeySet.contains(thisFunction.apply(e)));
    }

使用:

 @Test
    public void testDistinct2List() {
        List<Dish> dish1List = DishList.getDish1List();
        List<UmDish> umDish1List = DishList.getUmDish1List();
        // umDishFunction(组装key)
        Function<UmDish, String> umDishFunction = umDish -> umDish.getUmtype() + "-" + umDish.getUmname();

        // dishFunction(组装key)
        Function<Dish, String> function = umDish -> umDish.getType() + "-" + umDish.getName();

        // A=B
        List<Dish> collect1 = dish1List.stream().filter(distinctByOtherList(umDish1List, umDishFunction, function)).collect(Collectors.toList());
        // A>B
        List<Dish> collect2 = dish1List.stream().filter(distinctByOtherList(umDish1List, umDishFunction, function).negate()).collect(Collectors.toList());
        // B=A
        List<UmDish> collect3 = umDish1List.stream().filter(distinctByOtherList(dish1List, function, umDishFunction)).collect(Collectors.toList());
        // B>A
        List<UmDish> collect4 = umDish1List.stream().filter(distinctByOtherList(dish1List, function, umDishFunction).negate()).collect(Collectors.toList());
        // A=B的key(依据此key也可以对umDish1List、dish1List 过滤)
        Set<String> collect5 = dish1List.stream().filter(distinctByOtherList(umDish1List, umDishFunction, function)).map(function).collect(Collectors.toSet());

    }
  •  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值