第26条:优先考虑泛型

考虑第6条的简单堆栈实现:

public class Stack {
    pprivate Object[] elements;
    private int size = 0;
    private static final int DEFAULT_INITAL_CAPACITY = 16;

    public Stack() {
        elements = new Object[DEFAULT_INITAL_CAPACITY];
    }

    public void push(Object e) {
        ensureCapacity();
        elements[size++] = e;
    }

    public Object pop() {
        if(size == 0) {
            throw new EmptyStackException();
        }
        Object result = elements[--size];
        elements[size] = null;
        return result;
    }

    public boolean isEmpty() {
        return size == 0;
    }

    private void ensureCapacity() {
        if(elements.length == size)
            elements = Arrays.copyOf(elements, 2 * size + 1);
    }
}

将该类泛型化可以提高类型的安全性,方便客户端使用(无需显式强制转换类型)

首先用类型参数替换所有的Object类型:

public class Stack<E> {
    pprivate E[] elements;
    private int size = 0;
    private static final int DEFAULT_INITAL_CAPACITY = 16;

    public Stack() {
        elements = new E[DEFAULT_INITAL_CAPACITY];
    }

    public void push(E e) {
        ensureCapacity();
        elements[size++] = e;
    }

    public E pop() {
        if(size == 0) {
            throw new EmptyStackException();
        }
        E result = elements[--size];
        elements[size] = null;
        return result;
    }

    public boolean isEmpty() {
        return size == 0;
    }

    private void ensureCapacity() {
        if(elements.length == size)
            elements = Arrays.copyOf(elements, 2 * size + 1);
    }
}

由于不能创建不可具体化类型的数组,所有有错误(new E[DEFAULT)INITIAL_CAP]是不允许的)

解决方法:

1.创建一个Object数组,并将它转换成泛型数组类型:

elements = (E[]) new Object[DEFAULT_INITIAL_CAPACITY];

错误变成一条警告,因为可以保证类型安全,所以可以用SupressWarning注释忽略掉该警告。

2.将elements域的类型从E[]改为Object[]:

private Object[] elements;

E result = (E) elements[--size];

产生一条警告,因为可以保证类型安全,所以所以可以用SupressWarning注释忽略掉该警告。

实际中选择第二种方法较多,因为pop方法经常会被调用,频繁地类型转换会耗费时间。

在25条中,鼓励优先使用列表而非数组。实际上并不总能在泛型中使用列表。为了提高性能,列表不是Java提供的基本实现,如ArrayList就需要在数组上实现,而某些类,如HashMap为了提高性能,也在数组上实现。

时间: 2024-12-05 17:22:12

第26条:优先考虑泛型的相关文章

目标设立(17条)及时间管理(26条)

目标设立(17条)及时间管理(26条) 目标设立及时间管理是成功最重要的技巧. 行动是成功最重要的关键,请你百分之百的彻底实践,执行 每天进步一点点 有很多人想要行动.他知道他要行动.可是他还没有行动,有一个很重要的原因是因为他缺乏一些技巧和方法. 时间管理的源头来自于目标设定. 运用以下的关键技巧和方法,一个礼拜以后你会有很大的一个转换. 分享一些成功的技巧和方法: 一.目标设定和达成的关键(17条) 1.时间管理第一点就是要有一个明确的目标. 2.优先顺序你要排好. 3.目标要有一个期限.(

Effective Java 第三版——29. 优先考虑泛型

Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将近8年的时间,但随着Java 6,7,8,甚至9的发布,Java语言发生了深刻的变化. 在这里第一时间翻译成中文版.供大家学习分享之用. 29. 优先考虑泛型 参数化声明并使用JDK提供的泛型类型和方法通常不会太困难. 但编写自己的泛型类型有点困难,但值得努力学习. 考虑条目 7中的简单堆栈实现: // Ob

编写高质量代码改善C#程序的157个建议[优先考虑泛型、避免在泛型中声明静态成员、为泛型参数设定约束]

前言 泛型并不是C#语言一开始就带有的特性,而是在FCL2.0之后实现的新功能.基于泛型,我们得以将类型参数化,以便更大范围地进行代码复用.同时,它减少了泛型类及泛型方法中的转型,确保了类型安全.委托本身是一种引用类型,它保存的也是托管堆中对象的引用,只不过这个引用比较特殊,它是对方法的引用.事件本身也是委托,它是委托组,C#中提供了关键字event来对事件进行特别区分.一旦我们开始编写稍微复杂的C#代码,就肯定离不开泛型.委托和事件.本章将针对这三个方面进行说明. 这里也有一篇之前我对泛型的简

编写高质量代码改善C#程序的157个建议——建议32:总是优先考虑泛型

建议32:总是优先考虑泛型 泛型的优点是多方面的,无论泛型类还是泛型方法都同时具备可重用性.类型安全性和高效率等特性,这是非泛型和非泛型方法无法具备的. 以可重用性为例: class MyList { private int[] items; public int this[int i] { get { return items[i]; } set { this.items[i] = value; } } public int Count { get { return items.Length;

敏捷开发的26条至理名言 快速迭代式开发使用方法总结

敏捷开发真正的问题是什么?其实敏捷主要还是一种观念,一种意识,通过人来推动. 本文总结了26条有关敏捷开发的关键原则,如何快速迭代式开发,供读者参考借鉴,以指引敏捷软件开发团队. 1.完整地干完一件事后在开始另一件事:用厨房比喻来说就是:"先上这道菜,再开始做下一道".软件开发的最大问题就是同时开始几件事情,这将不可避免的造成某些工作被废弃,从而造成浪费.专注于一件事:完整地实现其功能:运行测试:编写文档:签入所有,把这当做一项工作完成,然后再开始下一件事. 2.不要破坏构建:非常明显

第26条:勿在分类中声明属性

属性是封装数据的方式(参见第6条). 属性只是定义实例变量及相关存取方法所用的“语法糖”,所以也应遵循同实例变量一样的规则. 分类机制,应该将其理解为一种手段,目标在于扩展类的功能,而非封装数据. 尽管从技术上说,分类里也可以声明属性,但这种做法应该尽量避免. 原因是:除了“class-continuation分类”(参见第27条)之外,其他分类都无法向类中新增实例变量,因此,它们无法把实现属性所需的实例变量合成出来. 所以开发者需要在分类中为该属性实现存取方法. 1)此时可以把方法声明为@dy

爱情有36计,不如看我这26条python技巧!

作者 Peter Gleeson 是一名数据科学家,日常工作几乎离不python.一路走来,他积累了不少有用的技巧和tips,现在就将这些技巧分享给大家.这些技巧将根据其首字母按A-Z的顺序进行展示. ALL OR ANY Python之所以成为这么一门受欢迎的语言一个原因是它的可读性和表达能力非常强.Python也因此经常被调侃为“可执行的伪代码”.不信你看: x = [True, True, False]if any(x):    print("At least one True"

阿里Android 26条规范经验及优化

1.Activity 间的数据通信,对于数据量比较大的,避免使用 Intent + Parcelable的方式,可以考虑 EventBus 等替代方案,以免造成 TransactionTooLargeException 2.Activity 间通过隐式 Intent 的跳转,在发出 Intent 之前必须通过 resolveActivity检查,避免找不到合适的调用组件,造成 ActivityNotFoundException 的异常. public void viewUrl(String ur

[Effective JavaScript 笔记]第26条:使用bind方法实现函数的柯里化

bind方法的作用,除了有绑定函数到对象外,我们来看看bind方法的一些其它应用. 简单示例 例子:假设有一个装配URL字符串的简单函数.代码如下 function simpleURL(protocol,domain,path){ return protocol+'://'+domain+'/'+path; } 要将特定站点的路径字符串构建为绝对路径URL.可以使用ES5中数组的map方法来实现.如下 var paths=['wengxuesong/','wengxuesong/p/556048