数组去重的方法java_五种数组去重方法的性能比较「建议收藏」

数组去重的方法java_五种数组去重方法的性能比较「建议收藏」为什么要写这篇文章之前参与面试一名外包程序员的时候,我要求他手写一个数组去重的方法,当时他使用了对象保存数值,通过查询去重。我表示表占用了空间,能不能只操作数组本身,减少空间占用。当时我想的是用indexOf和splice来操作数组,查询到index不等于i的时候,使用splice删除元素,之后自己跑了一遍发现函数执行时间非常长,所以想着研究一下效率比较高的去重方法。去重方法介…

大家好,又见面了,我是你们的朋友全栈君。

为什么要写这篇文章

之前参与面试一名外包程序员的时候,我要求他手写一个数组去重的方法,当时他使用了对象保存数值,通过查询去重。

我表示表占用了空间,能不能只操作数组本身,减少空间占用。

当时我想的是用 indexOf 和 splice 来操作数组,查询到 index 不等于 i 的时候,使用 splice 删除元素,之后自己跑了一遍发现函数执行时间非常长,所以想着研究一下效率比较高的去重方法。

去重方法介绍

外包同学写的表查询去重

//

function unique1(arr) {

let hash = {};

let result = [];

arr.forEach((num) => {

if (!hash[num]) {

hash[num] = 1;

result.push(num);

}

});

return result;

}

复制代码

思路:如果遍历到的数字不在表中,则更新表,更新结果数组。否则跳过

这个方法的优点是效率较高,缺点是占用了较多空间,可以看到使用的额外空间有一个查询对象和一个新的数组

ES6 的 Set 去重

function unique2(arr) {

return Array.from(new Set(arr));

}

复制代码

思路: 代码很简单,new 一个 Set,参数为需要去重的数组,Set 会自动删除重复的元素,再将 Set 转为数组返回。

这个方法的优点是效率更高,代码简单,思路清晰,缺点是可能会有兼容性问题

使用 filter 去重

function unique3(arr) {

return arr.filter((num, index) => {

return arr.indexOf(num) === index;

});

}

复制代码

思路: 这个方法与我上面面试时提到的思路差不多,利用 Array 自带的 filter 方法,返回 arr.indexOf(num) 等于 index 的num。原理就是 indexOf 会返回最先找到的数字的索引,假设数组是 [1, 1],在对第二个1使用 indexOf 方法时,返回的是第一个1的索引0。

这个方法的优点是可以在去重的时候插入对元素的操作,可拓展性强。

数组内部移动后返回部分数组

function unique4(arr) {

let right = arr.length – 1;

for (let i = 0; i < arr.length; i++) {

if (right <= i) {

break;

}

if (arr.indexOf(arr[i]) !== i) {

[arr[i], arr[right]] = [arr[right], arr[i]];

right–;

i–;

}

}

return arr.slice(0, right);

}

复制代码

思路:这个方法比较巧妙,从头遍历数组,如果元素在前面出现过,则将当前元素挪到最后面,继续遍历,直到遍历完所有元素,之后将那些被挪到后面的元素抛弃。

这个方法因为是直接操作数组,占用内存较少。

使用 reduce 去重

function unique5(arr) {

return arr.reduce((pre, cur) => {

if (pre.indexOf(cur) === -1) {

pre.push(cur);

}

return pre;

}, []);

}

复制代码

思路:reduce 是 Array 的一个迭代方法,参数为:迭代函数(参数为上一次回调的返回值(pre),当前遍历的元素(cur)),初始值。

在本例中传入一个空数组作为初始值,每次迭代时如果发现 pre 中没有当前元素,就把当前元素推入 pre,然后返回 pre 结束本次迭代。

这个方法花里胡哨的。

性能比较

随机生成五个数组,长度分别为10,100,1000,10000,100000,数值范围分别为0-10,0-100,0-1000,0-10000,0-100000。

分别使用这五个方法对五个数组进行去重后查看执行方法所用的时间。

8cca16ee3f9d3b3c55e3568af73f29d1.png

由图可知,方法1和方法2消耗时间最短,然后依次是3,4,5。处理数据较少时(10000以下)性能是差不多的。

而方法1和方法2中,方法1消耗较多空间,所以建议使用方法2也就是 Set。

b739ec46bb5c46d9c0aa4ce35ba1ea56.png

关于找一找教程网

本站文章仅代表作者观点,不代表本站立场,所有文章非营利性免费分享。

本站提供了软件编程、网站开发技术、服务器运维、人工智能等等IT技术文章,希望广大程序员努力学习,让我们用科技改变世界。

[五种数组去重方法的性能比较]http://www.zyiz.net/tech/detail-136619.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/150079.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • Mac(OSX)下媲美XShell的神器Termius「建议收藏」

    Mac(OSX)下媲美XShell的神器Termius「建议收藏」文章目录简介特点软件环境配置配置项配置密钥配置说明配置主机配置项简介XShell的大名不用多说,称它为Windows平台最好用的远程终端不为过吧。唯一不足的地方就是它只有Windows版本。所以今天跟大家介绍一款全平台的远程终端——Termius。Termius不仅涵盖了Windows、Linux、OSX,还变态得支持Android和iOS(以后在地铁、公交上都可以随时拿出手机来排查线上问题啦…………

  • linux如何安装docker_deepin安装docker

    linux如何安装docker_deepin安装docker安装前准备Linux系统下,版本需要不小于3.10.x目前docker安装只支持centOS7、centOS6.5也就是说centOS7是需要3.1以上内核centOS7是需要2.6以上内核linux输出命令uname-a这里用的是centOS7、3.1安装docker,大家最好也同步一下centOS7镜像可以从阿里云拉取一个,然后在搭建linux的时候跟之前版本差不多,只不过需要更改的点是vi/etc/sysconfig/network-scripts/ifcfg-

  • 基于opencv在摄像头ubuntu根据视频获取

    基于opencv在摄像头ubuntu根据视频获取

    2021年12月31日
  • 查看Redis版本信息

    查看Redis版本信息linux环境下查看redis的版本:查看redis的版本有两种方式:redis-server–version和redis-server-v得到的结果是:Redisserverv=3.0.7sha=00000000:0malloc=jemalloc-3.6.0bits=64build=c4d3f2c7214375c6redis-cli–version和redis-cl

  • ModelAndView 详解

    ModelAndView 详解当控制器处理完请求时,通常会将包含视图名称或视图对象以及一些模型属性的ModelAndView对象返回到DispatcherServlet。因此,经常需要在控制器中构造ModelAndView对象。ModelAndView类提供了几个重载的构造器和一些方便的方法,让你可以根据自己的喜好来构造ModelAndView对象。这些构造器和方法以类似的方式支持视图名称和视图对象。当你只有一个模型

  • .bat批处理基础

    .bat批处理基础批处理(Batch),也称为批处理脚本。顾名思义,批处理就是对某对象进行批量的处理,通常被认为是一种简化的脚本语言,它应用于DOS和Windows系统中。批处理文件的扩展名为bat。目前比较常见的批

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号