List?Set?Map?

现在有下面这样一个场景,

List?Set?Map?
你有一个集合,而它的作用只是用来被查询是否包含目标值,你是否也会习惯性的写出上面这段代码?
但是等等,看上去这段代码用流式写法写的非常简洁与流畅,但它的性能是最优选择吗?让我们来到ArrayList.contains(Object o)这个方法。

List?Set?Map?

可以看到,ArrayList为我们选择了最捞的查找方法——遍历法
没办法,作为一个最基本的List实现类,它已经做得很不错了,那么有没有更好的解决办法呢?

你好亲,有的呢

 

散列



散列简直就是为了查找而生的,他的基本实现逻辑就是将存放的对象进行hash计算(这个计算方式可以自己实现),然后根据计算值,将对象存放到对应位置

在散列中,如果要查找一个对象是否存在应该怎么办呢?
没错,计算这个对象的hash值,然后拿出散列中对应hash值的这个对象,然后equals比较一下

这样看,是不是比遍历高效多了? 基本就是o(n)到o(1)的计算复杂度的提升呀

于是在代码中,我进行了更改

List?Set?Map?

众所周知,Set是一个无序集合,里面的值只能存在一个,而这个接口的散列实现就是HashSet,简直完美符合我的需求!
(我还特地确认了一下是不是用的HashSet)

List?Set?Map?

这一切看起来已经很棒了是嘛,是的,对于一开始的List来说,已经有了很大的性能提升了,直到我因为好奇看了HashSet的底层实现……

List?Set?Map?

???

List?Set?Map?


不出所料,HashSet的add方法也是……

List?Set?Map?

这个“PRESENT”是一个静态对象。。。

所以绕了一圈,当我们遇到最初的那种情况应该怎么办呢?
我尝试使用了HashMap, 发现的确可以这么使用,

但是!

如果用的是流式写法,并且HashMap的Value如果为null时,会报这个问题

List?Set?Map?

在运行时会报异常

List?Set?Map?

如果不能传空而要传一个对象的话,那与HashSet的实现就没有什么区别了。

### 综上所述,如果只需要看一个集合里有没有目标值,那么HashSet可能是存放流式方法结果的最佳实现(也是默认实现)
如果是非流式的话,则可以直接用HashMap的put(key, null),而后使用contiansKey方法查找。当然,如果想要一个方便的散列实现,应该也不难,但是行业不通用的话,好像讨论的意义也不大哦

如果有什么比hashSet更好的无序散列集合的实现方式,请务必告诉我哦