Strream流使用遇到问题

Stream流与比较方法的碰撞

使用场景:

存在一个list<Integer> list = new ArrayList<>(),

一个Map<String, List<Integer>> map = new HashMap<>()

从map里面通过key去拿到集合valueList,判断list里面有那些值是valueList是没有的。

Stream流的noneMatch等价于!anyMatch

==equals

出现的情况:

demo里面使用!anyMatch + ==进行比较过滤,两个list的值都是一样(95)。那么通过代码过滤会的到一个空的list。就是判定list里面有的,但是valueList里面没有的。

同样的代码在项目里面得到却不是一个空list,而是一个95的list

同样代码,不同位置不同结果。

demo测试:
	private static String MEAL_TIME_MAP_CACHE = "meal_time_map_cache";
    private static String OPERATIVE_LIST_CACHE = "operative_list_cache";
    private static String INOPERATIVE_LIST_CACHE = "inoperative_list_cache";

    public static void main(String[] args) {
        List<Integer> operativeList = new ArrayList<>();
        operativeList.add(95);
        List<Integer> list1 = new ArrayList<>();
        list1.add(95);

        Map<String, List<Integer>> map = new HashMap<>();
        map.put(OPERATIVE_LIST_CACHE, list1);
        List<Integer> list = map.get(OPERATIVE_LIST_CACHE);

        List<Integer> newOperativeRemindList = operativeList.stream()
            .filter(i -> list.stream().noneMatch(j -> j == i)).collect(Collectors.toList());
        System.out.println(newOperativeRemindList);//打印[]
    }

list里面是95, valueList里面是95。通过上述代码打印出来的结果是[]

但是问题来了,项目代码里面

listList<Integer> operativeList = new ArrayList<>();出来,里面的值是从数据库数据获取的自增idadd进去的。

mapMap<String, List<Integer>> mealTimeMapCache = redisCacheUtils.getCacheMap(MEAL_TIME_MAP_CACHE); 缓存中拿出来的。

项目:
        List<Integer> operativeList = new ArrayList<>();
        List<Integer> inoperativeList = new ArrayList<>();
        packages.stream().forEach(i -> {
            Boolean checkMealTime = mealTImeBiz.checkMealTime(i.getMealTimeLimit(), i.getStartCondition(),
                             i.getEndCondition(), i.getConditionType(),i.getTimeRuleCondition(), i.getTimeHourCondition());
            if (checkMealTime) {
                operativeList.add(i.getId());
            }else {
                inoperativeList.add(i.getId());
            }
        });
        Map<String, List<Integer>> mealTimeMapCache = redisCacheUtils.getCacheMap(MEAL_TIME_MAP_CACHE);
        List<Integer> newRemindList = new ArrayList<>();
        if (mealTimeMapCache.isEmpty()) {
            newRemindList.addAll(operativeList);
        } else {
            List<Integer> newOperativeRemindList = operativeList.stream()
                .filter(i -> mealTimeMapCache.get(OPERATIVE_LIST_CACHE).stream().noneMatch(j -> j==i)).collect(Collectors.toList());
            List<Integer> newInoperativeRemindList = inoperativeList.stream()
                .filter(i -> !mealTimeMapCache.get(INOPERATIVE_LIST_CACHE).stream().anyMatch(j -> j == i)).collect(Collectors.toList());
            newRemindList.addAll(newOperativeRemindList);//newOperativeRemindList.size = 1
            newRemindList.addAll(newInoperativeRemindList);
        }

上述代码中,

operativeList.size = 1, [95]

mealTimeMapCache = {operative_list_cache=[95],inoperative_list_cache=[96]}

也就是说operativeList = [95], mealTimeMapCache.get(OPERATIVE_LIST_CACHE) = [95]

两个都是95的集合通过Stream流的noneMatch去匹配,应该是newOperativeRemindList.size = 0,但实际结果都是1

noneMatch:与allMatch相反,判断条件里的元素,所有的都不是,返回true

问题所在:

noneMatch里面的 j == i 通过比较的是引用地址,导致i,j两者能够相互匹配到返回true,所以 operativeListfilter true的时候没有出去。

== 替换成equals成功返回结果。

image-20231222174007723

image-20231222173934049

总结:

== 的作用:
  基本类型:比较值是否相等
  引用类型:比较内存地址值是否相等

equals 的作用:
  引用类型:默认情况下,比较内存地址值是否相等。可以按照需求逻辑,重写对象的equals方法。

= 的作用:
  基本类型:比较值是否相等
  引用类型:比较内存地址值是否相等

equals 的作用:
  引用类型:默认情况下,比较内存地址值是否相等。可以按照需求逻辑,重写对象的equals方法。

PS:可以延伸自己写代码比较一个基本类型的包装类对象使用 == 和 equals进行比较的结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值