zoukankan      html  css  js  c++  java
  • 泛型

        一般说,首先,这是仿制药?

          泛型是程序设计语言的一种特性。同意程序猿在强类型程序设计语言中编写代码是定义一些可变部分,那部分在使用前必须做出指明。

    各种程序设计语言和其编译器、执行环境对泛型的支持均不一样。将类型參数化以达到代码复用提高软件开发工作效率的一种数据类型。

    泛型类是引用类型,是对对象,主要引入了类型參数这个概念。

    ——来自百度百科。

        对于百科的解释,比較官方,也不是非常好理解,我觉得,泛型就是一种不同于集合类型的集合,该集合严格要求数据类型,提高了安全性。(当然这仅仅是我觉得,不准确)对照集合类型,使用泛型可以极大的提高集合类型的性能和安全性。

    避免隐式的装箱和拆箱为了看看使用泛型能为集合类型带来什么优点。先看看不用泛型时集合类型的表现。

    最典型的非泛型集合类型就是ArrayList了。这里便以它为例做介绍,考虑以下这段代码:

    <span style="font-size:18px;"><strong>ArrayList list = new ArrayList();
    constintListSize = 3;
    for (int i = 0; i <ListSize; i++) {
    list.Add(i);     
    }
    for (int i = 0; i <ListSize; i++) {
    int value = (int)list[i];
    Console.WriteLine(value);
    }</strong></span>
        假设对.NET的类型系统没有深刻的认识,可能会认为上面的代码没有不论什么问题。实际上,上面的代码属于典型的“能够执行”的代码,而非“好的”代码。由于ArrayList类型为了包容不论什么类型,所以它接受的參数为全部类型的基类Object,Object是一个引用类型,而int是一个值类型。因此当调用list.Add(i)时,存在一个装箱操作。同理,当从ArrayList中获得元素时,又须要进行一个拆箱操作:int value = (int)list[i]。这两个操作对于.NET来说是相对耗时的。尤其是当集合类型包括的元素比較多或值类型比較大(比方复杂的枚举或者结构)的时候。

    通过使用泛型,因为集合中的元素类型在编译时已经确定。就避免了装箱和拆箱的操作。这样便显著地提高了集合类型的性能。

    在.NET中,与ArrayList作用等同的泛型类型是List<T>,我们能够对它们做一个小小的測试:

    <span style="font-size:18px;"><strong>class Program {
    constintListSize = 500000;
    static void Main(string[] args) {
    UseArrayList();
    UseGenericList();
    Console.ReadKey();
    }
    private static void UseArrayList() {
    ArrayList list = new ArrayList();
    longstartTicks = DateTime.Now.Ticks;
    for (int i = 0; i <ListSize; i++) {
    list.Add(i);
    }
    for (int i = 0; i <ListSize; i++) {
    int value = (int)list[i];
    }
    longendTicks = DateTime.Now.Ticks;
    Console.WriteLine("使用ArrayList,耗时:{0} ticks", endTicks - startTicks);
    }
    private static void UseGenericList() {
    List<int> list = new List<int>();
    longstartTicks = DateTime.Now.Ticks;
    for (int i = 0; i <ListSize; i++) {
    list.Add(i);
    }
    for (int i = 0; i <ListSize; i++) {
    int value = list[i];
    }
    longendTicks = DateTime.Now.Ticks;
    Console.WriteLine("使用List<int>,耗时:{0} ticks", endTicks - startTicks);
    }
    }</strong></span>
        应该能够看到类似以下的输出:
          使用ArrayList。耗时:468750 ticks
          使用List<int>。耗时:156250 ticks

        依据机器的配置,输出结果差异可能会非常大。假设机器比較高档,有可能两个输出都是0。此时能够增大ListSize来获得输出。但无论如何。能够看到使用List<T>比使用ArrayList提高了差点儿相同3倍的性能。当使用一个大的值类型时,比方枚举或者结构。获得的差异还会更大。


    编译时的类型安全(泛型的最大优点,也是编程过程最头疼的地方)

        为什么这么说呢?相信大家在做系统尤其是.NET 版机房时,一定在类型不匹配上出现过非常多问题。主要就是在泛型的使用上。经常出现调试失败。某类型无法转换成某类型。当时非常头疼吧?事实上,这也是泛型的一个长处。这就是类型安全。这是什么意思呢?看以下一段代码:

    <span style="font-size:18px;"><strong>ArrayList list = new ArrayList();
    int i = 100;
    list.Add(i);
    string value = (string)list[0];</strong></span>
        有读者一眼就能够看出这段代码有问题。由于类型不匹配,加入到ArrayList中的是一个int类型,而获取时却想将它转换为string类型。可惜的是,编译器无法知道,由于对它来说,无论是int也好,string也好,它们都是Object类型。

    在编写代码时,编译器提供给开发人员的最大帮助之中的一个就是能够检查出错误,也就是常称的编译时错误(Compile time error)。当使用ArrayList时,对于上面的问题,编译器无能为力。由于它觉得其是合法的,编译能够顺利通过。

    这样的错误有时候隐藏在程序中非常难发现,最糟糕的情况是产品已经交付用户,而当用户在使用时不巧执行到这段代码,便会抛出一个异常,这时的错误,称为执行时错误(Runtime error)。

    通过使用泛型集合,这样的情况将不复存在,当试图进行类似上面的转换时,根本无法通过编译。这样有助于尽早发现问题:

    <span style="font-size:18px;"><strong>List<int> list = new List<int>();
    int i = 100;
    list.Add(i);
    string value = (string)list[0];   // 编译错误</strong></span>
        在做机房的时候。就一直想写一篇类似的关于泛型的博客。总结一下所学到的知识,直到前几天。看书看到才突然有感觉写下这篇博客,可能有错误,欢迎读者留言更正。

    版权声明:本文博客原创文章。博客,未经同意,不得转载。

  • 相关阅读:
    如何设计一个秒杀系统
    Leetcode题目437:路径总和III(递归-简单)
    Leetcode题目461:汉明距离(位运算-简单)
    Leetcode题目617:合并二叉树(递归-简单)
    分布式锁
    分布式搜索引擎
    数据库
    Java知识体系思维导图
    wav文件头详解,看懂wav文件
    推荐一个最近在学习的AI算法工程师手册,侵删
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/4724029.html
Copyright © 2011-2022 走看看