王小锤是一家电商网站的Java程序员,下午刚打开电脑,公司的运营妹子小美就过来找他:“小锤,你能帮我导一份数据吗?我需要昨天成为SVIP用户,并且之前给过差评的这些账号,不过要把一个叫大宝的账号去掉,他老板亲戚。”对于小美的需求,小锤从来没有拒绝过,这次也不例外。

答应小美之后,小锤心想,这么简单的事情,一个SQL就搞定了。小美又要夸我效率高了,想想还有点小激动呢。小锤打开电脑的一瞬间整个人都不好了。原来今天早上下班前,他才刚刚完成微服务的拆分。现在订单和用户已经分成了两个服务,评价表和用户等级表也已经在两个数据库里了。这就尴尬了,本来一个SQL能解决的事情,现在还需要跨服务调接口了。

不过小锤马上就有思路了:

小锤的思路

有了思路之后,小锤立刻就开始写代码了。

两分钟后……新鲜的代码出炉了(这里给个类似的Demo)。

 1public class NoBadReviewSVIP {2    public static void main(String[] args) {3        String[] svipArr = new String[]{"大宝","凉凉","Tom"};4        String[] badReviewUserArr = new String[]{"凉凉","Tom","大宝","小锤"};5        List<String> svips = new ArrayList<String>(Arrays.asList(svipArr));//从用户服务查6        svips.remove("大宝");7        List<String> badReviewUsers = new ArrayList<String>(Arrays.asList(badReviewUserArr));//从订单服务查8        if (svips.retainAll(badReviewUsers)) {9            System.out.println(svips);
10            System.out.println("有交集");
11        } else {
12            System.out.println("没有交集,告诉小美");
13        }
14    }
15}

小锤先运行了一下,发现结果是没有交集,于是小锤告诉小美:“没有你要的用户,昨天新的SVIP都没有给过差评。”小美说:“不可能,老板说有一个叫Tom的用户就给了差评,你再好好查查。”

小锤一查发现Tom真的给了差评,而且昨天刚刚成为SVIP。到底是哪里出了问题呢?小锤对着代码看了一个多小时也没发现问题,于是向身边的大锤请教。大锤只看了一眼,告诉他if的条件不对,让他看retainAll的具体实现。

retainAll的实现

于是小锤就开始看retainAll的源码了,发现它调用了一个batchRemove的私有方法。

 1    private boolean batchRemove(Collection<?> c, boolean complement) {2        final Object[] elementData = this.elementData;3        //w表示两个list的公共元素个数4        int r = 0, w = 0;5        boolean modified = false;6        try {7            for (; r < size; r++)8                //如果有公共元素,存入elementData9                if (c.contains(elementData[r]) == complement)
10                    elementData[w++] = elementData[r];
11        } finally {
12            // c.contains()抛异常,就把剩余元素复制到elementData
13            if (r != size) {
14                System.arraycopy(elementData, r,
15                                 elementData, w,
16                                 size - r);
17                //此时w为调用方list的长度
18                w += size - r;
19            }
20            //如果元素数量改变
21            if (w != size) {
22                // 多余空间教给GC
23                for (int i = w; i < size; i++)
24                    elementData[i] = null;
25                //记录list修改的次数
26                modCount += size - w;
27                //重新设置list大小
28                size = w;
29                //返回true
30                modified = true;
31            }
32        }
33        return modified;
34    }

这么一看小锤就明白了,对于

1listA.retainAll(listB)

listA中保存了listA和listB的交集,如果listA中元素数量改变,那么就返回true;如果listA的元素不变,则返回false。

也就是说,判断两个list是否有交集,只需要执行上述代码,然后判断listA的size是否大于0就可以了。

想通了这一点,小锤马上修改了代码,重新运行,得到正确结果,并且把结果告诉了小美。

万万没想到,小锤最后仍然没有得到小美的夸奖,因为所有的SVIP都给了差评,小美要负责挨个询问原因并且帮助他们解决问题,所以根本没有时间搭理小锤。

日常自黑

斐波那契程序员

留言请移步博客,或者点击阅读原文

https://jackeyzhe.github.io/2019/03/13/retainAll%E5%87%BD%E6%95%B0%E9%82%A3%E7%82%B9%E5%84%BF%E4%BA%8B/

王小锤学Java:retainAll函数那点儿事相关推荐

  1. “中国诺贝尔奖”首位女得主王小云:哈希函数是区块链的起源性技术,区块链已扩展到供应链金融等多领域...

    "哈希函数.数字签名算法.加密算法是密码学三类基础算法,其中哈希函数是起源性技术." 本文旨在传递更多市场信息,不构成任何投资建议. 火星财经APP(微信:hxcj24h)一线报道 ...

  2. 小学期学Java有感

    大二末的小学期,为期四周的时间将要学完Java这门课程. 由于已经有了C,C++,数据结构算法等基础,这门课的进度可谓飞快.从最初的HelloWorld到今天未完成的视频压缩,其间才过去了11天. 由 ...

  3. 手把手教我班小姐姐学java之面向对象

    真的光看不练假把式,编程主要还是打代码,就像我班这位小姐姐一样,看的不少,视频也看了,书也读了,就是写不出程序来. 木的办法,只能小白我来帮忙了!!! 例题1-简单继承 创建GeometricObje ...

  4. 手把手教我班小姐姐学java之多态

    文章目录 多态 动态绑定 声明类型 实际类型 工作机制 对象转换和Instanceof操作符 概念: 隐式转换(向上转型.自动类型转换) 显式转换( 向下转型.强制类型转换) instanceof关键 ...

  5. 小明学java基础系列——Java 类加载

    Java类加载学习笔记 一.基本概念 1.1 基本文件类型和概念 1.2 idea程序示例 1.2.1 idea-java源文件 1.2.2 idea-java字节码 1.2.3 idea-类加载 1 ...

  6. 【Java】跟着小丛学Java第三阶段:Java核心API

    异常处理 什么是异常 在编写Java应用程序时,可能会遇到各种类型的错误,例如输入无效的数据或尝试访问不存在的文件等.当这种错误发生时,Java会抛出一个异常,这可能会导致程序崩溃或产生不可预测的结果 ...

  7. 手把手教我班小姐姐学java之方法重写与方法重载

    方法重写 子类从父类中继承方法.有事,子类需要修改父类中定义的方法的实现,这就是方法重写. 重写的好处在于子类可以根据需要,定义特定于自己的行为. 在面向对象原则里,重写意味着可以重写任何现有方法.实 ...

  8. 2019王小的Java学习之路

    文章背景 身边有个非常要好的朋友王某某,因为是发小的关系,之后文章统称为王小. 大专毕业后 顺利 的被安排进了某某工厂工作,工作一段时间后,尽管工作比较轻松,却无法忍受终日的流水线生活,经过我的介绍, ...

  9. mstem函数怎么定义_小白该怎么学Java开发 Java编程重要点有哪些

    小白怎么学Java开发?Java编程重要点有哪些?在Java的学习中,面向对象应该是Java技术的重中之重,虽然在生活中没有对象可以面对,但在技术中还是要一直接触面对对象,而且不可避免.下面小编为大家 ...

最新文章

  1. 第二十五课.元学习MetaLearning
  2. oracle行转列与列转行
  3. 函数中数据存储的问题
  4. 工具的特性_16 个好用的 Code Review 工具
  5. 深入理解mysql系列_深入理解MySQL系列之锁
  6. c++遍历文件夹下的文件_算法面试|开发者必备|使用递归函数进行无限分类及文件夹遍历...
  7. 快速设置 Docker 的三种网络代理配置
  8. Linux中arp表的老化机制
  9. flash乱码解决方案
  10. 指南针经纬度分秒格式转换10进制经纬度
  11. Windows XP默认用户自动登录
  12. Android:H5 通过 URL Scheme 拉起app应用
  13. Organ at Risk Segmentation for Head and Neck Cancer using Stratified Learning and Neural Architectur
  14. Mac升级文件不见了怎么恢复?
  15. 远程控制桌面,手机外网远程桌面连接内网的实现过程,详细图文并茂
  16. STM32进入Standby模式并唤醒
  17. Filecoin系列 - 源码分析 - CPU SHA扩展
  18. 系统安全启动总结思考
  19. Criteria和DetachedCriteria
  20. 雄关漫道真如铁, 而今迈步从头越

热门文章

  1. Linux网络——DNS域名解析服务
  2. 批量抓取图虫作者页作品图片的方法
  3. chrome设置微信ua_模拟UA实现访问只能在微信上打开的网页
  4. 【数据库】云数据库rds是什么意思?有什么优势?
  5. 北京首都国际机场1号航站楼、2号航站楼、3号航站楼航空公司名单
  6. 信息论与编码_从信息论谈数字孪生系统的大行其道
  7. LambdaQueryWrapper和QueryWapper的区别
  8. 2018个人年度总结:我是如何从嵌入式开发到服务器开发对接天猫精灵、小爱智能音箱服务器!懵懂 | 奋斗 | 进阶 | 信心
  9. iDrac6 虚拟控制台 连接失败
  10. 喜讯 | 哈特公寓荣誉获最佳新锐公寓奖