List数组高效率去重

List数组高效率去重

一、环境准备–生成包含重复元素的list数组

/**
 * 生成包含重复元素的list数组
 * @return
 */
private static List<String> getList(){
    List<String> list = new ArrayList<>();
    for (int i = 1; i <= 10000; i++) {
        list.add(String.valueOf(i));
    }
    for (int i = 10000; i >= 1; i--) {
        list.add(String.valueOf(i));
    }
    return list;
}

二、常规方法–使用list.contains()方法去重

代码实现:

/**
 * 使用 list.contains() 方法去重
 * @param testList
 */
private static void useListContains(List<String> testList){
    System.out.println("contains 开始去重,条数:" + testList.size());
    List<String> list = new ArrayList<>();
    for (String str : testList) {
        if (!list.contains(str)) {
            list.add(str);
        }
    }
    System.out.println("contains 去重完毕,条数:" + list.size());
}

测试该方法去重时长:

public static void main(String[] args) {
    StopWatch stopWatch = new StopWatch();
    // 生成list
    List<String> list = getList();
    stopWatch.start();
    // 常规去重,采用list.contain()
    useListContains(list);
    stopWatch.stop();
    System.out.println("去重共耗时: " + stopWatch.getTotalTimeMillis());
}

结果如下:

在这里插入图片描述

list.contains()去重原理:
在这里插入图片描述

以上是ArrayListcontains源码的查重逻辑,从源码中我们能看出contains方法采用的是for循环遍历数组的方式进行元素的逐一对比,时间复杂度为O(n).

三、高效方法–使用HashSet特性去重

代码实现:

/**
 * 使用 hashSet的值不能重复的特性去重
 * @param testList
 */
private static void useHashSet(List<String> testList){
    System.out.println("hashSet 开始去重,条数:" + testList.size());
    List<String> list = new ArrayList<>(new HashSet<>(testList));
    System.out.println("hashSet 去重完毕,条数:" + list.size());
}

测试该方法去重时长:

public static void main(String[] args) {
    StopWatch stopWatch = new StopWatch();
    // 生成list
    List<String> list = getList();
    stopWatch.start();
    // hashSet去重
    useHashSet(list);
    stopWatch.stop();
    System.out.println("去重共耗时: " + stopWatch.getTotalTimeMillis());
}

结果如下:
在这里插入图片描述

HashSet特性去重原理:

在这里插入图片描述

new HashSet<>(testList)

新建HashSet对象时采用的的是add方法,此处涉及到HashSet的底层原理,当值相同时,则会添加相同存放位置的链表或者红黑树上,匹对的方法也是直接使用equal方法进行判断,所以使用HashSet特性进行去重的时间复杂度为O(1).

顺带提一句,HashMapcontainsKey方法查询key是否重复的过程时间复杂度也是O(1)

如果不清楚HashSet底层原理的,可直接通过一下链接了解,图示较为简洁清楚。
HashSet底层原理

四、总结

ArrayListcontains去重时间复杂度为O(n)

HashSet特性去重的时间复杂度为O(1)

综上,可以得出HashSet特性去重效率远高于ArrayListcontains去重方法,而且随着查重参数越多,两者的时间差越明显。

猜你喜欢

转载自blog.csdn.net/xiri_/article/details/131192117