java list去重_JAVA基础-List去重的6种方式[通俗易懂]

java list去重_JAVA基础-List去重的6种方式[通俗易懂]简述java开发中经常会遇到List去重这个工作,现在就来整理一下List去重的6种方式。方法代码以及效率测试模拟测试数据相关代码:importjava.util.LinkedList;importjava.util.List;/***@ClassName:ListCleatMain*@Description:模拟数据进行List去重测试*@author:ssqxx*@date:…

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

简述

java开发中经常会遇到List去重这个工作,现在就来整理一下List去重的6种方式。

方法代码以及效率测试

模拟测试数据

相关代码:

import java.util.LinkedList;

import java.util.List;

/**

* @ClassName: ListCleatMain

* @Description: 模拟数据进行List去重测试

* @author: ssqxx

* @date: 2020-11-18

* @version 1.0

*/

public class ListCleatMain {

public static void main(String[] args) {

//声明一个新的List

List list = new LinkedList<>();

//数据装载开始时间

Long startTime = System.currentTimeMillis();

System.out.println(“数据装载开始时间:” + startTime);

//模拟添加200000个Integer

for (int i=0;i<200000;i++){

Integer in =(int)(Math.random()*10+1);

list.add(in);

}

//数据装载结束时间

Long endTime = System.currentTimeMillis();

System.out.println(“数据装载结束时间:” + endTime);

//数据装载时差

System.out.println(“数据装载时差:” + (endTime – startTime));

//原数据遍历打印

System.out.println(“原数据:”);

list.forEach( li-> {

System.out.print(li + ” “);

});

System.out.println();

//开始时间

long startClear = System.currentTimeMillis();

System.out.println(“开始时间:” + startClear);

//去重-双for循环去重

List newList = ListClearByDoubleFor.listRemove(list);

//去重-Contains方法去重

// List newList = ListClearByContains.listRemove(list);

//去重-利用HashSet去重

// List newList = ListClearByHashSet.listRemove(list);

//去重-利用TreeSet去重

// List newList = ListClearByTreeSet.listRemove(list);

//去重-利用LinkedHashSet去重

// List newList = ListClearByLinkedHashSet.listRemove(list);

//去重-利用Java8的stream去重

// List newList = ListClearByStream.listRemove(list);

//结束时间

long endClear = System.currentTimeMillis();

System.out.println(“结束时间:” + endClear);

//时间差

System.out.println(“去重用时:” + (endClear – startClear));

//去重后数据遍历打印

System.out.println(“新数据:”);

newList.forEach(li -> {

System.out.print(li + ” “);

});

}

}

双for循环

实现思想:

使用两个for循环遍历集合所有元素,然后进行判断是否有相同元素,如果有,则去除。(有序)

相关代码:

import java.util.List;

/**

* @ClassName: ListClearByDoubleFor

* @Description: 双for循环进行list去重

* @author: ssqxx

* @date: 2020-11-18

* @version 1.0

*/

public class ListClearByDoubleFor {

/**

* 数据去重

* @param list

* @return list

*/

public static List listRemove(List list){

//双for循环进行list去重

for (int i=0; i

for (int j=i+1; j

if (list.get(i).equals(list.get(j))){

list.remove(j);

j–;

}

}

}

return list;

}

}

效率测试:

数据装载开始时间:1605667320390

数据装载结束时间:1605667320407

数据装载时差:17

原数据:

9 8 3 2 3 10 4 9 5 3 1 7 6 8 7 8 9 5 5 8 2 2 ……(20W数据)

开始时间:1605667320811

结束时间:1605667413269

去重用时:92458(这还用再测?)

新数据:

9 8 3 2 10 4 5 1 7 6

————————————————–

它不配!!!!!

List的contains方法

实现思想:

利用List集合contains方法循环遍历,先创建新的List集合,接着循环遍历原来的List集合,判断新集合是否包含有旧集合,如果有,则不添加至新集合,否则添加。(有序)

相关代码:

import java.util.ArrayList;

import java.util.List;

/**

* @ClassName: ListClearByContains

* @Description: 利用List集合contains方法循环遍历去重

* @author: ssqxx

* @date: 2020-11-18

* @version 1.0

*/

public class ListClearByContains {

/**

* 数据去重

* @param list

* @return list

*/

public static List listRemove(List list){

//利用List集合contains方法循环遍历去重

List newList = new ArrayList();

list.forEach(li -> {

//判断新集合是否包含有,如果不包含有,则存入新集合中

if (!newList.contains(li)){

newList.add(li);

}

});

return newList;

}

}

效率测试:

数据装载开始时间:1605674583323

数据装载结束时间:1605674583340

数据装载时差:17

原数据:

8 10 7 3 7 6 6 1 7 6 2 8 9 6 6 5 2 6 5 5 3 1 ……(20W数据)

开始时间:1605674583756

结束时间:1605674583771

去重用时:15/13/13/13/11(5次测试)

新数据:

8 10 7 3 6 1 2 9 5 4

————————————————–

开始时间:1605680194498

结束时间:1605680194553

去重用时:55/57/56/61/64(打印原数据)

去重用时:144/120/127/124/125(不打印原数据)

新数据:

17 3 2 16 13 6 18 1 10 5 11 7 20 9 15 14 12 8 19 4

HashSet方法

实现思想:

HashSet实现了Set接口,不允许出现重复元素。可以基于这个想法,把List集合所有元素存入HashSet对象,接着把List集合元素全部清空,最后把HashSet对象元素全部添加至List集合中,这样就可以保证不出现重复元素。而HashSet有一个构造函数,在初始化时可以直接添加元素。其中,HashSet不能保证顺序不变,所以此方式不能保证List集合原来的顺序不变。 (无序)

相关代码:

import java.util.HashSet;

import java.util.Iterator;

import java.util.List;

/**

* @ClassName: ListClearByHashSet

* @Description: List集合放入HashSet中利用HashSet实现Set接口的无重复元素特性去重

* @author: ssqxx

* @date: 2020-11-18

* @version 1.0

*/

public class ListClearByHashSet {

/**

* 数据去重

* @param list

* @return list

*/

public static List listRemove(List list){

//List集合放入HashSet中利用HashSet实现Set接口的无重复元素特性去重

HashSet set = new HashSet(list);

list.clear();

list.add(set);

// Iterator it = set.iterator();

// while (it.hasNext()){

// list.add(it.next());

// }

return list;

}

}

效率测试:

数据装载开始时间:1605675392758

数据装载结束时间:1605675392776

数据装载时差:18

原数据:

3 6 1 1 7 6 9 2 8 6 4 7 1 9 5 5 4 3 3 1 10 8 10 10……(20w数据)

开始时间:1605675393184

结束时间:1605675393200

去重用时:16/20/15/12/15(5次测试)

新数据:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

————————————————–

开始时间:1605680088596

结束时间:1605680088641

去重用时:45/45/46/52/44(打印原数据)

去重用时:167/163/160/164/166(不打印原数据)

新数据:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]

TreeSet方法

实现思想:

TreeSet集合也是实现Set接口,是一个有序的,并且无重复元素集合。(有序)

相关代码:

import java.util.*;

/**

* @ClassName: ListClearByTreeSet

* @Description: List集合放入TreeSet中利用HashSet实现Set接口的无重复元素特性去重

* @author: ssqxx

* @date: 2020-11-18

* @version 1.0

*/

public class ListClearByTreeSet {

/**

* 数据去重

* @param list

* @return list

*/

public static List listRemove(List list){

//List集合放入TreeSet中利用HashSet实现Set接口的无重复元素特性去重

TreeSet set = new TreeSet(list);

list.clear();

list.add(set);

// Iterator it = set.iterator();

// while (it.hasNext()){

// list.add(it.next());

// }

return list;

}

}

效率测试:

数据装载开始时间:1605675683470

数据装载结束时间:1605675683487

数据装载时差:17

原数据:

8 10 4 3 8 10 8 2 1 9 1 3 1 1 8 3 4 4 10 6 6 2……(20W数据)

开始时间:1605675683881

结束时间:1605675683909

去重用时:28/25/29/26/26(5次测试)

新数据:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

————————————————–

开始时间:1605679953606

结束时间:1605679953697

去重用时:91/94/104/103/101(打印原数据)

去重用时:112/119/123/113/117(不打印原数据)

新数据:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]

LinkedHashSet方法

实现思想:

LinkedHashSet是一个实现Set接口将ArrayList删除重复数据的最佳方法。LinkedHashSet在内部完成两件事:删除重复数据,保持添加到其中的数据的顺序。(有序)

相关代码:

import java.util.*;

/**

* @ClassName: ListClearByLinkedHashSet

* @Description: List集合放入LinkedHashSet中利用LinkedHashSet实现Set接口的无重复元素特性去重

* @author: ssqxx

* @date: 2020-11-18

* @version 1.0

*/

public class ListClearByLinkedHashSet {

/**

* 数据去重

* @param list

* @return list

*/

public static List listRemove(List list){

//List集合放入LinkedHashSet中利用LinkedHashSet实现Set接口的无重复元素特性去重

LinkedHashSet hashSet = new LinkedHashSet(list);

list.clear();

list.add(hashSet);

// Iterator iterator = hashSet.iterator();

// while(iterator.hasNext()){

// list.add(iterator.next());

// }

return list;

}

}

效率测试:

数据装载开始时间:1605675839400

数据装载结束时间:1605675839417

数据装载时差:17

原数据:

2 7 5 1 4 4 1 5 1 9 10 7 3 9 7 3 6 7 1 1 4……(20W数据)

开始时间:1605675839818

结束时间:1605675839835

去重用时:17/16/14/17/19(5次测试)

新数据:

[2, 7, 5, 1, 4, 9, 10, 3, 6, 8]

————————————————–

开始时间:1605679823889

结束时间:1605679823938

去重用时:49/43/42/42/44(打印原数据)

去重用时:173/159/160/163/169(不打印原数据)

新数据:

[12, 1, 9, 6, 3, 8, 19, 13, 5, 16, 2, 10, 11, 15, 17, 4, 7, 20, 14, 18]

Java8的stream方法

实现思想:

要从arraylist中删除重复项,我们也可以使用java 8 stream api。使用steam的distinct()方法返回一个由不同数据组成的流,通过对象的equals()方法进行比较。 (有序)

相关代码:

import java.util.List;

import java.util.stream.Collectors;

/**

* @ClassName: ListClearByStream

* @Description: 使用java8新特性stream实现List去重

* @author: ssqxx

* @date: 2020-11-18

* @version 1.0

*/

public class ListClearByStream {

/**

* 数据去重

* @param list

* @return list

*/

public static List listRemove(List list){

//使用java8新特性stream实现List去重

List newList = (List) list.stream().distinct().collect(Collectors.toList());

return newList;

}

}

效率测试:

数据装载开始时间:1605679132825

数据装载结束时间:1605679132841

数据装载时差:16

原数据:

7 3 4 6 5 2 7 8 5 6 7 4 3 8 6 5 2 4 5 5 2 10 2……(20W数据)

开始时间:1605679133233

结束时间:1605679133248

去重用时:15/14/13/19/16(5次测试)

新数据:

7 3 4 6 5 2 8 10 9 1

————————————————–

开始时间:1605679582415

结束时间:1605679582443

去重用时:28/31/35/27/31(打印原数据)

去重用时:94/81/96/96/87(不打印原数据)

新数据:

8 15 4 3 17 1 10 19 12 9 16 20 7 6 18 13 2 5 14 11

结论

随机数在200000范围10以内(平均值):

使用两个for循环实现List去重:94258毫秒

使用List集合contains方法循环遍历去重时间:13毫秒

使用HashSet实现List去重时间:16毫秒

使用TreeSet实现List去重时间:27毫秒

使用LinkedHashSet实现List去重时间:17毫秒

使用java8新特性stream实现List去重:15毫秒

随机数在2000000范围20以内(平均值):

使用两个for循环实现List去重:已放弃!!!!

使用List集合contains方法循环遍历去重时间:128毫秒

使用HashSet实现List去重时间:164毫秒

使用TreeSet实现List去重时间:117毫秒

使用LinkedHashSet实现List去重时间:165毫秒

使用java8新特性stream实现List去重:91毫秒

随机数在20000000范围20以内(一次值):

使用两个for循环实现List去重:已放弃!!!!

使用List集合contains方法循环遍历去重时间:612毫秒

使用HashSet实现List去重时间:334毫秒

使用TreeSet实现List去重时间:813毫秒

使用LinkedHashSet实现List去重时间:364毫秒

使用java8新特性stream实现List去重:214毫秒

结论简述:

目前表现最好的是java8新特性stream实现的list去除,不论是数据量大小;

HashSet、TreeSet、LinkedHashSet都有实现Set接口,所以速度都不会很慢,但是在过了1000W这个数量的list后去重速度骤降,HashSet,LinkedHashSet依旧稳定快速;整体上HashSet>LinkedHashSet>TreeSet。不过HashSet是无序的,若想有序可以使用LinkedHashSet;

list集合的contains方法在数据量不大的时候能去重速度也挺快的,甚至能超过HashSet,但数据量大(500W)之后,去重速度骤降,数据量不大的list去重可以使用;

双for循环进行list去重就……算了,放弃吧!

整体排序:

500W数据以下:

(有序)stream>contains>LinkedHashSet>TreeSet>for

(无序)stream>contains>HashSet>LinkedHashSet>TreeSet>for

500W数据以上:

(有序)stream>LinkedHashSet>contains>TreeSet>for

(无序)stream>HashSet>LinkedHashSet>contains>TreeSet>for

以上数据为自测数据,可能与实际应用会存在误差,下次再测试一下String(字符串)的list排序。

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

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

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

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

(0)


相关推荐

  • Go学习——密码学

    Go学习——密码学

  • mt4平台如何下载_mt4交易平台

    mt4平台如何下载_mt4交易平台当前我们若要顺势进场交易,除了要选择一个好的交易平台,一个实用的投资软件也必不可少。虽然目前市面上流行着多种mt4平台,优质型的不少,但也不乏“山寨版”,后者多为不法平台为了恶意操纵显示的行情以坑骗投资者的资金而自主研发的,危害性极大。那mt4平台哪个比较好用更安全呢?务必要留意其下载渠道的正规性,通常,正规安全有监管的平台具有好的市场口碑,能提供更可靠的投资环境,其专有的mt4平台是为安全的下载渠道。投资者除了要知道mt4平台哪个比较好用更好之外,还应充分了解下载何种软件更利于我们顺畅交易。考虑到当前

  • 使用 Captcha 扩展包 为 Laravel 5 应用生成验证码

    使用 Captcha 扩展包 为 Laravel 5 应用生成验证码

    2021年10月26日
  • 分布式事务框架Seata

    分布式事务框架Seata分布式事务中常见的三种解决方案目录一、分布式事务前奏 二、柔性事务解决方案架构 (一)、基于可靠消息的最终一致性方案概述 (二)、TCC事务补偿型方案 (三)、最大努力通知型 三、基于可靠消息的最终一致性方案详解 (一)、消息发送一致性 (二)、保证消息一致的变通做法 (三)、常规MQ消息处理流程和特点 (四)、消息重复发送问题和业务接口幂等性设计 (五)、本地消息服务方案 (六)、独立消息服务方案 (七)、消息服务子系统的设计实现 一、分布式事务

    2022年10月27日
  • exe免杀加壳工具包_grep过滤不想要的

    exe免杀加壳工具包_grep过滤不想要的简介该工具是由Arks7使用Go语言开发的一个免杀生成器模板,目前可以过国内主流杀毒。GitHub地址:https://github.com/Arks7/Go_Bypass用法使用CobaltStrike生成payload,输出格式为Raw,4.3版本需要勾选X64,如图:将生成的文件放在Go_Bypass项目目录下,然后执行goenv-wGOPROXY=https://goproxy.io,direct配置代理,否则编译报错。然后运行gorunmain.go,使用默认配置一路回车即

  • 用js来实现那些数据结构03(数组篇03-排序及多维数组)

    终于,这是有关于数组的最后一篇,下一篇会真真切切给大家带来数据结构在js中的实现方式。那么这篇文章还是得啰嗦一下数组的相关知识,因为数组真的太重要了!不要怀疑数组在JS中的重要性与实用性。这篇文章分为

发表回复

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

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