Java中5种List的去重方法及它们的效率对比

简介: Java中5种List的去重方法及它们的效率对比

使用两个for循环实现List去重(有序)

/**
     * 使用两个for循环实现List去重(有序)
     *
     * @param list
     * @return
     */
    public static List removeDuplicationBy2For(List<Integer> list) {
        for (int i = 0; i < list.size(); i++) {
            for (int j = i + 1; j < list.size(); j++) {
                if (list.get(i).equals(list.get(j))) {
                    list.remove(j);
                }
            }
        }
        return list;
    }

使用List集合contains方法循环遍历(有序)

/**
     * 使用List集合contains方法循环遍历(有序)
     *
     * @param list
     */
    public static List removeDuplicationByContains(List<Integer> list) {
        List<Integer> newList = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            boolean isContains = newList.contains(list.get(i));
            if (!isContains) {
                newList.add(list.get(i));
            }
        }
        list.clear();
        list.addAll(newList);
        return list;
    }

使用HashSet实现List去重(无序)

/**
     * 使用HashSet实现List去重(无序)
     *
     * @param list
     */
    public static List removeDuplicationByHashSet(List<Integer> list) {
        HashSet hashSet = new HashSet(list);
        list.clear();
        list.addAll(hashSet);
        return list;
    }

使用TreeSet实现List去重(有序)

/**
     * 使用TreeSet实现List去重(有序)
     *
     * @param list
     */
    public static List removeDuplicationByTreeSet(List<Integer> list) {
        TreeSet treeSet = new TreeSet(list);
        list.clear();
        list.addAll(treeSet);
        return list;
    }

使用java8的stream实现List去重(有序)

/**
     * 使用java8的stream实现List去重(有序)
     *
     * @param list
     */
    public static List removeDuplicationByStream(List<Integer> list) {
        List<Integer> collect = list.stream().distinct().collect(Collectors.toList());
        return collect;
    }

使用Main方法测试


 public static void main(String[] args) {
        List<Integer> list1 = new ArrayList<>();
        List<Integer> list2 = new ArrayList<>();
        List<Integer> list3 = new ArrayList<>();
        List<Integer> list4 = new ArrayList<>();
        List<Integer> list5 = new ArrayList<>();
        Random random = new Random();
        for (int i = 0; i < 100000; i++) {
            int value = random.nextInt(500);
            list1.add(value);
            list2.add(value);
            list3.add(value);
            list4.add(value);
            list5.add(value);
        }
        long startTime;
        long endTime;
        startTime = System.currentTimeMillis();
        removeDuplicationByHashSet(list1);
        endTime = System.currentTimeMillis();
        System.out.println("使用HashSet实现List去重时间:" + (endTime - startTime) + "毫秒");
        startTime = System.currentTimeMillis();
        removeDuplicationByTreeSet(list2);
        endTime = System.currentTimeMillis();
        System.out.println("使用TreeSet实现List去重时间:" + (endTime - startTime) + "毫秒");
        startTime = System.currentTimeMillis();
        removeDuplicationByStream(list3);
        endTime = System.currentTimeMillis();
        System.out.println("使用java8新特性stream实现List去重:" + (endTime - startTime) + "毫秒");
        startTime = System.currentTimeMillis();
        removeDuplicationBy2For(list4);
        endTime = System.currentTimeMillis();
        System.out.println("使用两个for循环实现List去重:" + (endTime - startTime) + "毫秒");
        startTime = System.currentTimeMillis();
        removeDuplicationByContains(list5);
        endTime = System.currentTimeMillis();
        System.out.println("使用List集合contains方法循环遍历:" + (endTime - startTime) + "毫秒");
    }

结果:
使用HashSet实现List去重时间:21毫秒
使用TreeSet实现List去重时间:28毫秒
使用java8新特性stream实现List去重:80毫秒
使用两个for循环实现List去重:470毫秒
使用List集合contains方法循环遍历:42毫秒

随机数在100范围内:

使用HashSet实现List去重时间:15毫秒
使用TreeSet实现List去重时间:18毫秒
使用java8新特性stream实现List去重:64毫秒
使用两个for循环实现List去重:289毫秒
使用List集合contains方法循环遍历:16毫秒

随机数在10000范围内:

使用HashSet实现List去重时间:20毫秒
使用TreeSet实现List去重时间:42毫秒
使用java8新特性stream实现List去重:67毫秒
使用两个for循环实现List去重:3904毫秒
使用List集合contains方法循环遍历:845毫秒

相关文章
|
19天前
|
XML Java API
List与String相互转化方法汇总
本文汇总了List与String相互转化的多种方法,包括使用`String.join()`、`StringBuilder`、Java 8的Stream API、Apache Commons Lang3的`StringUtils.join()`以及Guava的`Joiner.on()`方法实现List转String;同时介绍了使用`split()`方法、正则表达式、Apache Commons Lang3的`StringUtils.split()`及Guava的`Splitter.on()`方法实现String转List。
List与String相互转化方法汇总
|
6天前
|
Java
Java的方法详解
Java的方法是类中的重要组成部分,用于定义类的行为。方法可以接收参数、执行操作并返回结果。其基本语法包括返回类型、方法名、参数列表和方法体。方法支持重载,即同名但参数不同的多个方法;静态方法则直接通过类名调用,无需实例化。此外,Java还支持可变参数,允许方法接收不定数量的参数。通过访问修饰符如`public`、`protected`、`private`,可以控制方法的可见性。方法是实现类功能的基本单元,增强了程序的灵活性和复用性。
|
13天前
|
存储 Java 程序员
优化Java多线程应用:是创建Thread对象直接调用start()方法?还是用个变量调用?
这篇文章探讨了Java中两种创建和启动线程的方法,并分析了它们的区别。作者建议直接调用 `Thread` 对象的 `start()` 方法,而非保持强引用,以避免内存泄漏、简化线程生命周期管理,并减少不必要的线程控制。文章详细解释了这种方法在使用 `ThreadLocal` 时的优势,并提供了代码示例。作者洛小豆,文章来源于稀土掘金。
|
18天前
|
Java
用JAVA架建List集合为树形结构的代码方法
这段代码定义了一个表示树形结构的 `Node` 类和一个用于构建树形结构的 `TreeController`。`Node` 类包含基本属性如 `id`、`pid`、`name` 和 `type`,以及子节点列表 `children`。`TreeController` 包含初始化节点列表并将其转换为树形结构的方法。通过过滤和分组操作实现树形结构的构建。详情可见:[代码示例链接1](http://www.zidongmutanji.com/zsjx/43551.html),[代码效果参考链接2](https://www.257342.com/sitemap/post.html)。
28 5
|
15天前
|
Java API 开发者
代码小妙招:用Java轻松获取List交集数据
在Java中获取两个 `List`的交集可以通过 `retainAll`方法和Java 8引入的流操作来实现。使用 `retainAll`方法更为直接,但会修改原始 `List`的内容。而使用流则提供了不修改原始 `List`、更为灵活的处理方式。开发者可以根据具体的需求和场景,选择最适合的方法来实现。了解和掌握这些方法,能够帮助开发者在实际开发中更高效地处理集合相关的问题。
13 1
|
4天前
|
JavaScript 前端开发 Java
通过JUnit5访问Java静态、私有、保护变量和方法
在《通过Gtest访问C++静态、私有、保护变量和方法》一文中介绍了如何通过Gtest访问C++静态、私有、保护变量和方法,本文介绍如何通过Junit5访问Java静态、私有、保护变量和方法。
11 0
|
17天前
|
Java 开发者
探索Java中的Lambda表达式:简化代码的现代方法
【8月更文挑战第31天】Lambda表达式在Java 8中首次亮相,为Java开发者提供了一种更简洁、灵活的编程方式。它不仅减少了代码量,还提升了代码的可读性和可维护性。本文将通过实际示例,展示Lambda表达式如何简化集合操作和事件处理,同时探讨其对函数式编程范式的支持。
|
3天前
|
存储 缓存 安全
【Java面试题汇总】多线程、JUC、锁篇(2023版)
线程和进程的区别、CAS的ABA问题、AQS、哪些地方使用了CAS、怎么保证线程安全、线程同步方式、synchronized的用法及原理、Lock、volatile、线程的六个状态、ThreadLocal、线程通信方式、创建方式、两种创建线程池的方法、线程池设置合适的线程数、线程安全的集合?ConcurrentHashMap、JUC
【Java面试题汇总】多线程、JUC、锁篇(2023版)
|
14天前
|
监控 Java 调度
【Java学习】多线程&JUC万字超详解
本文详细介绍了多线程的概念和三种实现方式,还有一些常见的成员方法,CPU的调动方式,多线程的生命周期,还有线程安全问题,锁和死锁的概念,以及等待唤醒机制,阻塞队列,多线程的六种状态,线程池等
75 6
【Java学习】多线程&JUC万字超详解
|
7天前
|
Java 调度 开发者
Java并发编程:深入理解线程池
在Java的世界中,线程池是提升应用性能、实现高效并发处理的关键工具。本文将深入浅出地介绍线程池的核心概念、工作原理以及如何在实际应用中有效利用线程池来优化资源管理和任务调度。通过本文的学习,读者能够掌握线程池的基本使用技巧,并理解其背后的设计哲学。