c# List去重

c# List去重需求:对List集合中的元素去重。实现:有三种方式可以使用-使用Linq中distinct()方法-借助hashset-使用for循环遍历,这种方法在数据量大时,运行速度比较慢代码示例使用distinct()//使用distinct()List<string>lst1=newList<string>(){“as”,”lio”,”sdrf”,”asd”,”lio”};varr.

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

  1. 需求 : 对List集合中的元素去重。
  2. 实现: 有三种方式可以使用
    – 使用Linq中distinct()方法
    – 借助hashset
    – 使用for循环遍历,这种方法在数据量大时,运行速度比较慢

代码示例

  • 使用distinct()

  //使用distinct()
  List<string> lst1 = new List<string>() 
  { 
    "as", "lio", "sdrf", "asd", "lio" };
            var  reslst =lst1.Distinct().ToList();
  • 使用hashset

 public static List<T> RemoveT<T>(List<T> items)
        { 
   
            HashSet<T> set = new HashSet<T>();

            var res = new List<T>();//返回

            for (int i = 0; i < items.Count; i++)
            { 
   
                if (!set.Contains(items[i]))
                { 
   
                    set.Add(items[i]);
                    res.Add(items[i]);
                }
            }
            return res;
        }
  • 使用for-loop

 public  static List<string> ForLoopRemove(List<string> items)
        { 
   
            List<string> output = new List<string>();
            for (int i = 0; i < items.Count; i++)
            { 
   
                bool flag = false;
                //每个元素都与其他这个元素前面的比较,如果前面没有,则添加,否则不添加
                for (int z = 0; z < i; z++)
                { 
   
                    if (items[z] == items[i])
                    { 
   
                        flag = true;
                        break;
                    }
                }
                if (!flag)
                { 
   
                    output.Add(items[i]);
                }
            }
            return output;
        }

测试三种方式的运行速度
代码示例

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

namespace ConsoleApp2
{ 
   
    class Program
    { 
   
        static void Main(string[] args)
        { 
   
            //list 去重,三种方法
            for (int test = 0; test < 3; test++)
            { 
   
                // 获取测试数据
                var testData = GetTestData(test);
                var max = testData.Item3;///执行次数

                var s1 = Stopwatch.StartNew();
                for (int i = 0; i < max; i++)
                { 
   
                    // 方法 1: use Distinct.
                    var unique = testData.Item2.Distinct().ToList();
                }
                s1.Stop();
                var s2 = Stopwatch.StartNew();
                for (int i = 0; i < max; i++)
                { 
   
                    // 方法 2: use HashSet.
                    var unique = Method.RemoveT(testData.Item2);
                }
                s2.Stop();
                var s3 = Stopwatch.StartNew();
                for (int i = 0; i < max; i++)
                { 
   
                    // 方法 3: use nested for-loop.
                    var unique = Method.ForLoopRemove(testData.Item2);
                }
                s3.Stop();
                // 打印信息.
                Console.WriteLine(testData.Item1);
                //调用时间.
                Console.WriteLine(s1.Elapsed.TotalMilliseconds + " ms");
                Console.WriteLine(s2.Elapsed.TotalMilliseconds + " ms");
                Console.WriteLine(s3.Elapsed.TotalMilliseconds + " ms");
            }

            //结论: 当数据量少时,直接使用for-loop 遍历数据即可;
            //当数据量大时,使用hashSet 或者时linq的distinct()方法
            List<string> testLst=  GetListWithDuplicates(100, 20);
            Method.RemoveRepeat(testLst);

            //实现按照对象的某个字段去重。

            List<Student> lst = new List<Student>();
            lst.Add(new Student { 
    No = 23, name = "李磊" });
            lst.Add(new Student { 
    No = 45, name = "david" });
            lst.Add(new Student { 
    No = 12, name = "lily" });

            lst.Add(new Student { 
    No = 23, name = "李磊" });
            lst.Add(new Student { 
    No = 45, name = "david" });
            lst.Add(new Student { 
    No = 72, name = "lily" });

            var res=  lst.Distinct(new ItemEqualityComparer());
            foreach (var item in res)
            { 
   
                Console.WriteLine($"distinct: {item.No}---{item.name}");
            }


            Console.ReadKey();
        }

      

        /// <summary>
        /// 生成测试数据,最后的一个参数,表示方法被调用的次数
        /// </summary>
        /// <param name="test"></param>
        /// <returns></returns>
        static Tuple<string, List<string>, int> GetTestData(int test)
        { 
   
            // Tuple contains description string, list, the unique element count, and iterations for test.
            switch (test)
            { 
   
                default:
                case 0:
                    return new Tuple<string, List<string>, int>("10 ELEMENT LIST, 0 DUPLICATES",
                        GetListWithDuplicates(10, 0),
                        100000);
                case 1:
                    return new Tuple<string, List<string>, int>("300 ELEMENT LIST, 100 DUPLICATES",
                        GetListWithDuplicates(200, 100),
                        1000);
                case 2:
                    return new Tuple<string, List<string>, int>("3000 ELEMENT LIST, 1000 DUPLICATES",
                        GetListWithDuplicates(2000, 1000),
                        100);
            }
        }

        public static List<string> GetListWithDuplicates(int len, int repeatNum)
        { 
   
            const string duplicateString = "bird";
            List<string> result = new List<string>();
            for (int i = 0; i < len; i++)
            { 
   
                result.Add("cat" + i);

                if (repeatNum > 0)
                { 
   
                    result.Add(duplicateString);
                    repeatNum--;
                }
            }

            for (int i = 0; i < repeatNum; i++)
            { 
   
                result.Add(duplicateString);
            }
            return result;
        }
    }


    /// //
  #region 按照对象的某个字段去重
    public class Student
    { 
   
        public string name;
        public int No;
        
    }
    /// <summary>
    /// 按照学号判断
    /// </summary>
    public class ItemEqualityComparer : IEqualityComparer<Student>
    { 
   
        public bool Equals(Student x, Student y)
        { 
   
            return x.No == y.No;
        }

        public int GetHashCode(Student obj)
        { 
   
            return obj.No.GetHashCode();
        }
    }
    #endregion

}

调用方法的封装

using System;
using System.Collections.Generic;


namespace ConsoleApp2
{ 
   
    public static class Method
    { 
   

        /// <summary>
        /// 使用两个循环,但是在数据量大时,这种方法比较慢
        /// </summary>
        /// <param name="items"></param>
        /// <returns></returns>
        public  static List<string> ForLoopRemove(List<string> items)
        { 
   
            List<string> output = new List<string>();
            for (int i = 0; i < items.Count; i++)
            { 
   
                bool flag = false;
                //每个元素都与其他这个元素前面的比较,如果前面没有,则添加,否则不添加
                for (int z = 0; z < i; z++)
                { 
   
                    if (items[z] == items[i])
                    { 
   
                        flag = true;
                        break;
                    }
                }
                if (!flag)
                { 
   
                    output.Add(items[i]);
                }
            }
            return output;
        }

        /// <summary>
        /// 使用hashset去重
        /// </summary>
        /// <param name="lst"></param>
       public  static void RemoveRepeat(List<string> lst)
        { 
   
            Console.WriteLine("intput :" + lst.Count);

            HashSet<string> set = new HashSet<string>();
            foreach (string item in lst)
            { 
   
                set.Add(item);
            }
            Console.WriteLine(set.Count);

            lst.Clear();
            lst.AddRange(set);
            Console.WriteLine("outPut: "+lst.Count);
        }

        /// <summary>
        /// 使用hashset去重的泛型方法
        /// </summary>
        /// <param name="items"></param>
       public static List<T> RemoveT<T>(List<T> items)
        { 
   
            HashSet<T> set = new HashSet<T>();

            var res = new List<T>();//返回

            for (int i = 0; i < items.Count; i++)
            { 
   
                if (!set.Contains(items[i]))
                { 
   
                    set.Add(items[i]);
                    res.Add(items[i]);
                }
            }
            return res;
        }

    }
}

  • 代码中,也提供了对象集合按照对象的某个字段进行去重的方法。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/141341.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • linux任务管理器_redhat和centos的区别

    linux任务管理器_redhat和centos的区别本文将向你介绍RedFlagDesktopLinux10(红旗Linux10)的新功能及新特性,让你对RedFlag的桌面版创新有一个了解,以下介绍6点和其他Linux发行版有着与众不同的地方。想获取该版本请看想要红旗桌面操作系统10(RedFlagDesktopLinux10)的请联系红旗官方一文。红旗Linux10的新功能/新特性介绍1、全新的UI设计全新的图标集和彩色表情包让用…

    2022年8月20日
    5
  • 怪诞行为学丹 . 艾瑞里_怪诞心理学epub

    怪诞行为学丹 . 艾瑞里_怪诞心理学epub郑重声明:本号收录的电子书均来源于互联网或网友分享,链接内容仅作分享交流学习使用,不用于任何商业用途,版权归原作者和出版社所有,如果喜欢,请支持和购买正版,谢谢。下载地址:http://pan.63

    2022年8月3日
    5
  • 解决docker容器部署dubbo服务时,注册到注册中心的地址是docker容器内的地址

    解决docker容器部署dubbo服务时,注册到注册中心的地址是docker容器内的地址

    2021年8月3日
    71
  • 在html中加入外部css样式,如何引入CSS样式表?

    在html中加入外部css样式,如何引入CSS样式表?CSS用于修饰网页样式,但是,如果希望CSS修饰的样式起作用,就必须在html档中引入CSS样式表。引入样式表的常用方式有三种,即行内式、内嵌式、外链式,具体介绍如下。1.行内式行内式也称内联样式,是通过标记的Istyle属性来设置标记的样式,其基本语法格式如下:内容标记名>上述语法中,style是标记的属性,实际上任何HTML标记都拥有style属性,用来设置行内式。属性和属性值的书写…

    2022年7月14日
    20
  • 如何在Windows上下载,安装或卸载PyCharm?「建议收藏」

    如何在Windows上下载,安装或卸载PyCharm?「建议收藏」PyCharmisaPythonIDEthatprovideseasinesstodevelopedPythonApplication.PyCharmprovidesalotofusefulfeatureslikesmartcodecompletion,codeinspection,on-the-flyerrorhighlighting,qui…

    2022年8月29日
    3
  • 视频要不要开hdr_hdr在什么情况下使用

    视频要不要开hdr_hdr在什么情况下使用最近两年HDR这个概念可谓是铺天盖地而来,手机也好PC也好电视也好,都拼命往自己头上扣HDR的帽子。而在某些发烧友眼中,如果看片子不带HDR,堪比步兵变骑兵,一下子变得索然无味。然而,新事物往往也伴随着众多新坑,特别是在软硬件环境复杂的PC平台,稍有不慎就会摔得脸青鼻肿,播HDR的效果甚至不如播普通的片子。PC播HDR的大坑有几何?PC并不是专门为视频播放设计的机器,和专业的蓝光机等播放器相比…

    2022年9月14日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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