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。通过上述代码打印出来的结果是[]
但是问题来了,项目代码里面
list
是List<Integer> operativeList = new ArrayList<>();
出来,里面的值是从数据库数据获取的自增idadd
进去的。
map
是Map<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
,所以 operativeList
的filter
true的时候没有出去。
将==
替换成equals
成功返回结果。
总结:
== 的作用:
基本类型:比较值是否相等
引用类型:比较内存地址值是否相等
equals 的作用:
引用类型:默认情况下,比较内存地址值是否相等。可以按照需求逻辑,重写对象的equals方法。
= 的作用:
基本类型:比较值是否相等
引用类型:比较内存地址值是否相等
equals 的作用:
引用类型:默认情况下,比较内存地址值是否相等。可以按照需求逻辑,重写对象的equals方法。
PS:可以延伸自己写代码比较一个基本类型的包装类对象使用 == 和 equals进行比较的结果