java之去重方式,以及效率问题

之前面试被问到关于java如何去重的问题,当时没怎么留意,今天刚好项目中用到了,所以记录一下。

实体类:

/**
 * 用户类
 */
class User{
private String username;
private String password;

    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

测试类:

 public static void main(String[] args) {

        ArrayList<User> arrayList = new ArrayList<>();
        long currentTimeMillis = System.currentTimeMillis();
        int f = 100000;
        for(int i = 0; i < f; i++){
            arrayList.add(new User(""+i, "7878"));
        }
        Iterator<User> iterator = arrayList.iterator();
        Set<String> hashSet = new HashSet<>();
        LinkedList<User> newList = new LinkedList<>();

        //  第一种:set集合去重,不改变原有的顺序,根据username唯一标识去重
        while (iterator.hasNext()){
            User u = iterator.next();
            // 根据set不能存放相同值的特性
            if(!StringUtils.isEmpty(u.getUsername())){
                if (hashSet.add(u.getUsername())){
                    //  将其重新放入在LinkedList中
                    newList.add(u);
                }
            }
        }
        long currentTimeMillis1_1 = System.currentTimeMillis();
        System.out.println("第一种set集合去重,不改变原有的顺序:"+(currentTimeMillis1_1 - currentTimeMillis));

        // 第二种:遍历后判断赋给另一个list集合,利用List的contains方法循环遍历
        List<User> listNew=new ArrayList<>();
        for (User str:arrayList) {
            if(!listNew.contains(str)){
                listNew.add(str);
            }
        }
        long currentTimeMillis1_2 = System.currentTimeMillis();
        System.out.println("第二种:遍历后判断赋给另一个list集合,利用List的contains方法循环遍历:"+(currentTimeMillis1_2 - currentTimeMillis1_1));

        //  第三种:set去重
        Set set = new HashSet();
        List<String> listNew2=new ArrayList<>();
        set.addAll(arrayList);
        listNew2.addAll(set);

        long currentTimeMillis1_3 = System.currentTimeMillis();
        System.out.println(" 第三种:set去重"+(currentTimeMillis1_3 - currentTimeMillis1_2));

        //  第四种:set去重(缩减为一行)
        List<String> listNew3=new ArrayList<>(new HashSet(arrayList));

        long currentTimeMillis1_4 = System.currentTimeMillis();
        System.out.println("第四种:set去重(缩减为一行)"+(currentTimeMillis1_4 - currentTimeMillis1_3));

        //  第五种:去重并按自然顺序排序
       /* TreeSet treeSet = new TreeSet(arrayList);
        List tempList = new ArrayList();
        tempList.addAll(treeSet);
        //List<User> listNew4=new ArrayList<>(new TreeSet<User>(arrayList));

        long currentTimeMillis1_5 = System.currentTimeMillis();
        System.out.println(currentTimeMillis1_5 - currentTimeMillis1_4);*/

        //  第六种:双重for循环,去重
        for(int i = 0 ; i < arrayList.size() - 1; i ++){
            for(int j = arrayList.size() - 1; j > i; j --){
                if(arrayList.get(j).equals(arrayList.get(i))){
                    arrayList.remove(j);
                }
            }
        }
        long currentTimeMillis1_6 = System.currentTimeMillis();
        System.out.println("第六种:双重for循环,去重"+(currentTimeMillis1_6 - currentTimeMillis1_4));

        //  第七种:利用HashSet不能添加重复数据的特性 由于HashSet不能保证添加顺序,所以只能作为判断条件
        HashSet<User> set2 = new HashSet<>(arrayList.size());
        List<User> result = new ArrayList<>(arrayList.size());
        for (User str3 : arrayList) {
            if (set2.add(str3)) {
                result.add(str3);
            }
        }
        arrayList.clear();
        arrayList.addAll(result);
        long currentTimeMillis1_7 = System.currentTimeMillis();
        System.out.println("第七种:利用HashSet不能添加重复数据的特性 由于HashSet不能保证添加顺序,所以只能作为判断条件"+(currentTimeMillis1_7 - currentTimeMillis1_6));

        //   第八种:利用LinkedHashSet不能添加重复数据并能保证添加顺序的特性
        LinkedHashSet<User> set5 = new LinkedHashSet<>(arrayList.size());
        set5.addAll(arrayList);
        arrayList.clear();
        arrayList.addAll(set5);

        long currentTimeMillis1_8 = System.currentTimeMillis();
        System.out.println("第八种:利用LinkedHashSet不能添加重复数据并能保证添加顺序的特性"+(currentTimeMillis1_8 - currentTimeMillis1_7));

    }

控制台输出:

提示:在数据量大的情况下,最好不要使用第二种和第六种,速度太慢了

至于效率问题大家自己根据实际情况选择吧。

原文地址:https://www.cnblogs.com/dqcer/p/9531337.html

时间: 2024-10-08 23:44:28

java之去重方式,以及效率问题的相关文章

java List去重方式及效率对比

对List去重并保证添加顺序主要有三种方式: 方式一,利用HashSet不能添加重复数据的特性 由于HashSet不能保证添加顺序,所以只能作为判断条件: private static void removeDuplicate(List<String> list) { HashSet<String> set = new HashSet<String>(list.size()); List<String> result = new ArrayList<S

List集合去重方式及效率对比

List集合相信大家在开发过程中几乎都会用到.有时候难免会遇到集合里的数据是重复的,需要进行去除.然而,去重方式有好几种方式,你用的是哪种方式呢?去重方式效率是否是最高效.最优的呢?今天就给大家讲解一下List集合去重的常见及常用的四种方式. 01 实现思路:使用两个for循环遍历集合所有元素,然后进行判断是否有相同元素,如果有,则去除.这种方式是大部分最先想到的,也是最简单的实现方式.其中,这种方式可以保证List集合原来的顺序不变. 代码实现: /*** notes:使用两个for循环实现L

java list 去重

Guava ImmutableSet源码去重处理,Hash处理 - 汪小哥 - CSDN博客 https://blog.csdn.net/u012881904/article/details/68954347 Guava Collections使用介绍[超级强大] - kuyuyingzi的专栏 - CSDN博客https://blog.csdn.net/kuyuyingzi/article/details/30529053 Google Guava Collections 使用介绍https:

java int转String所有方式的效率对比与深入解析

在java中,大家肯定都会遇到int类型转String类型的情形,知其然知其所以然,总结加分析一下,int类型转String类型有以下几种方式: a+"" String.valueOf(a) Integer.toString(a) 以上三种方法在实际使用过程中都是没有问题的,但是效率上还是有些许差别的,所以写个小程序来对比一下他们的效率: int a = 123456789; long start = System.currentTimeMillis(); for (int i=0;

java int转String全部方式的效率对照与深入解析

在java中,大家肯定都会遇到int类型转String类型的情形,知其然知其所以然.总结加分析一下,int类型转String类型有下面几种方式: a+"" String.valueOf(a) Integer.toString(a) 以上三种方法在实际使用过程中都是没有问题的,可是效率上还是有些许区别的,所以写个小程序来对照一下他们的效率: int a = 123456789; long start = System.currentTimeMillis(); for (int i=0;

java多种文件复制方式以及效率比较

1.背景 java复制文件的方式其实有很多种,可以分为 传统的字节流读写复制FileInputStream,FileOutputStream,BufferedInputStream,BufferedOutputStream 传统的字符流读写复制FileReader,FileWriter,BufferWriter,BufferedWriter,BufferedReader NIO系列的FileChannel FileChannel+缓冲 java.nio.Files.copy() 第三方包中的Fi

Java Map遍历方式的选择

1. 阐述 对于Java中Map的遍历方式,很多文章都推荐使用entrySet,认为其比keySet的效率高很多.理由是:entrySet方法一次拿到所有key和value的集合:而keySet拿到的只是key的集合,针对每个key,都要去Map中额外查找一次value,从而降低了总体效率.那么实际情况如何呢? 为了解遍历性能的真实差距,包括在遍历key+value.遍历key.遍历value等不同场景下的差异,我试着进行了一些对比测试. 2. 对比测试 一开始只进行了简单的测试,但结果却表明k

专题三、ArrayList遍历方式以及效率比较

一.遍历方式 ArrayList支持三种遍历方式. 1.第一种,随机访问,它是通过索引值去遍历 由于ArrayList实现了RandomAccess接口,它支持通过索引值去随机访问元素. 代码如下: // 基本的forfor (int i = 0; i < size; i++){    value = list.get(i);} 2.第二种,foreach语句 foreach语句是java5的新特征之一,在遍历数组.集合方面,foreach为开发人员提供了极大的方便. 代码如下: for (In

Java 初始化字段方式和顺序

Java 初始化字段方式和顺序: 类加载时直接初始化静态字段; 类加载时调用静态方法初始化静态字段; 实例化对象时,在调用构造函数之前代码块中初始化字段; 实例化对象时,在调用构造函数之时初始化字段; 初始化字段顺序1->2->3->4 代码如下: public class Employee { //实例化对象时,在调用构造函数之前前初始化字段; private int id; // 实例化对象时初始化为0 private String name; // 实例化对象时初始化为null p