java编程思想阅读笔记(三)

final 方法

之所以要使用final 方法,可能是出于对两方面理由的考虑。第一个是为方法“上锁”,防止任何继承类改变它的本来含义。设计程序时,若希望一个方法的行为在继承期间保持变,而且不可被覆盖或改写,就可以采取这种做法。 采用 final 方法的第二个理由是程序执行的效率。将一个方法设成 final 后,编译器就可以把对那个方法的所有调用都置入“嵌入”调用里。只要编译器发现一个 final 方法调用,就会(根据它自己的判断)忽略为执行方法调用机制而采取的常规代码插入方法(将自变量压入堆栈;跳至方法代码并执行它;跳回来;清除堆栈自变量;最后对返回值进行处理)。相反,它会用方法主体内实际代码的一个副本来替换方法调用。这样做可避免方法调用时的系统开销。当然,若方法体积太大,那么程序也会变得雍肿,可能受到到不到嵌入代码所带来的任何性能提升。因为任何提升都被花在方法内部的时间抵消了。Java 编译器能自动侦测这些情况,并颇为“明智”地决定是否嵌入一个 final 方法。然而,最好还是不要完全相信编译器能正确地作出所有判断。通常,只有在方法的代码量非常少,或者想明确禁止方法被覆盖的时候,才应考虑将一个方法设为final。 
类内所有private 方法都自动成为final。由于我们不能访问一个private 方法,所以它绝对不会被其他方法覆盖(若强行这样做,编译器会给出错误提示)。可为一个private 方法添加 final 指示符,但却不能为那个方法提供任何额外的含义。 

final类是无法继承的,同时也有出于效率的嫌疑。

集合


集合库考虑到了“容纳自己对象”的问题,并将其分割成两个明确的概念: 
(1) 集合(Collection):一组单独的元素,通常应用了某种规则。在这里,一个 List(列表)必须按特定的顺序容纳元素,而一个Set(集)不可包含任何重复的元素。相反,“包”(Bag)的概念未在新的集合库中实现,因为“列表”已提供了类似的功能。 
(2) 映射(Map):一系列“键-值”对(这已在散列表身上得到了充分的体现)。从表面看,这似乎应该成为一个“键-值”对的“集合”,但假若试图按那种方式实现它,就会发现实现过程相当笨拙。这进一步证明了应该分离成单独的概念。另一方面,可以方便地查看 Map 的某个部分。只需创建一个集合,然后用它表示那一部分即可。这样一来,Map 就可以返回自己键的一个Set、一个包含自己值的List 或者包含自己“键-值”对的一个List。和数组相似,Map 可方便扩充到多个“维”,毋需涉及任何新概念。只需简单地在一个Map 里包含其他 Map(后者又可以包含更多的Map,以此类推)。 

集合能做的所有事情(亦可对 Set 和List 做同样的事情,尽管 List 还提供了一些额外的功能)。Map 不是从 Collection 继承的,所以要单独对待。 

List(接口) 顺序是 List 最重要的特性;它可保证元素按照规定的顺序排列。List 为 Collection 添加了大量方法,以便我们在 List 中部插入和删除元素(只推荐对LinkedList 这样做)。List 也会生成一个ListIterator(列表反复器),利用它可在一个列表里朝两个方向遍历,同时插入和删除位于列表中部的元素(同样地,只建议对 LinkedList 这样做) ArrayList* 由一个数组后推得到的 List。作为一个常规用途的对象容器使用,用于替换原先的Vector。允许我们快速访问元素,但在从列表中部插入和删除元素时,速度却嫌稍慢。一般只应该用ListIterator 对一个ArrayList 进行向前和向后遍历,不要用它删除和插入元素;与 LinkedList 相比,它的效率要低许多 LinkedList 提供优化的顺序访性能,同时可以高效率地在列表中部进行插入和删除操作。但在进行随机访问时,速度却相当慢,此时应换用 ArrayList。也提供了 addFirst(),addLast(),getFirst(),getLast(),removeFirst() 以及removeLast()(未在任何接口或基础类中定义),以便将其作为一个规格、队列以及一个双向队列使用 。

Set(接口) 添加到 Set 的每个元素都必须是独一无二的;否则Set 就不会添加重复的元素。添加到 Set 里的对象必须定义equals(),从而建立对象的唯一性。Set 拥有与 Collection 完全相同的接口。一个 Set不能保证自己可按任何特定的顺序维持自己的元素 HashSet* 用于除非常小的以外的所有Set。对象也必须定义 hashCode() ArraySet 由一个数组后推得到的 Set。面向非常小的Set 设计,特别是那些需要频繁创建和删除的对于小Set,与HashSet 相比,ArraySet 创建和反复所需付出的代价都要小得多。但随着 Set 的增大,它的性能也会大打折扣。不需要HashCode() 。TreeSet 由一个“红黑树”后推得到的顺序 Set(注释⑦)。这样一来,我们就可以从一个Set 里提到一个顺序集合。(可是我发现好像没有arrayset啊)

Map(接口) 维持“键-值”对应关系(对),以便通过一个键查找相应的值 HashMap* 基于一个散列表实现(用它代替Hashtable)。针对“键-值”对的插入和检索,这种形式具有最稳定的性能。可通过构建器对这一性能进行调整,以便设置散列表的“能力”和“装载因子” ArrayMap 由一个 ArrayList 后推得到的 Map。对反复的顺序提供了精确的控制。面向非常小的 Map 设计,特别是那些需要经常创建和删除的。对于非常小的Map,创建和反复所付出的代价要比 HashMap 低得多。但在Map 变大以后,性能也会相应地大幅度降低 TreeMap 在一个“红-黑”树的基础上实现。查看键或者“键-值”对时,它们会按固定的顺序排列(取决于Comparable 或Comparator,稍后即会讲到)。TreeMap 最大的好处就是我们得到的是已排好序的结果。TreeMap 是含有 subMap()方法的唯一一种Map,利用它可以返回树的一部分 

选择

list

在ArrayList 中进行随机访问(即get())以及循环反复是最划得来的;但对于LinkedList 却是一个不小的开销。但另一方面,在列表中部进行插入和删除操作对于 LinkedList 来说却比ArrayList 划算得多。我们最好的做法也许是先选择一个ArrayList 作为自己的默认起点。以后若发现由于大量的插入和删除造成了性能的降低,再考虑换成LinkedList 不迟。

遍历list:

Iterator it = list.iterator();
        while(it.hasNext()){
//            it.next();
            System.out.println(it.next());
        }

map

ArrayMap 的性能也要比HashMap 差——除反复循环时以外。而在使用 Map 时,反复的作用通常并不重要(get()通常是我们时间花得最多的地方)。TreeMap 提供了出色的 put()以及反复时间,但 get()的性能并不佳。但是,我们为什么仍然需要使用TreeMap 呢?这样一来,我们可以不把它作为Map 使用,而作为创建顺序列表的一种途径。树的本质在于它总是顺序排列的,不必特别进行排序(它的排序方式马上就要讲到)。一旦填充了一个TreeMap,就可以调用 keySet()来获得键的一个Set“景象”。然后用 toArray() 253
产生包含了那些键的一个数组。随后,可用static 方法Array.binarySearch()快速查找排好序的数组中的内容。当然,也许只有在HashMap 的行为不可接受的时候,才需要采用这种做法。因为HashMap 的设计宗旨就是进行快速的检索操作。最后,当我们使用 Map 时,首要的选择应该是 HashMap。只有在极少数情况下才需要考虑其他方法。 

典型的遍历map方法:

for(Map.Entry<String,String> entry : map.entrySet()){
            
        };

Java中Comparable和Comparator区别小结




第1章 对象入门 1.1 抽象的进步 1.2 对象的接口 1.3 实现方案的隐藏 1.4 方案的重复使用 1.5 继承:重新使用接口 1.5.1 改善基础类: 尽管extends关键字暗示着我们要为接口“扩展”新功能,但实情并非肯定如此。为区分我们的新类,第二个办法是改变基础类一个现有函数的行为。我们将其称作“改善”那个函数。 为改善一个函数,只需为衍生类的函数建立一个新定义即可。我们的目标是:“尽管使用的函数接口未变,但它的新版本具有不同的表现”。 1.5.2 等价和类似关系 1.6 多形对象的互换使用 1.6.1 动态绑定 1.6.2 抽象的基础类和接口 1.7 对象的创建和存在时间 1.7.1 集合与继承器 1.7.2 单根结构 1.7.3 集合库与方便使用集合 1.7.4 清除时的困境:由谁负责清除? 1.8 违例控制:解决错误 1.9 多线程 1.10 永久性 1.11 Java和因特网: 既然Java不过另一种类型的程序设计语言,大家可能会奇怪它为什么值得如此重视,为什么还有这么多的人认为它是计算机程序设计的一个里程碑呢?如果您来自一个传统的程序设计背景,那么答案在刚开始的时候并不是很明显。Java除了可解决传统的程序设计问题以外,还能解决World Wide Web(万维网)上的编程问题。 1.11.1 什么是Web? 1.11.2 客户端编程 1.11.3 服务器端编程 1.11.4 一个独立的领域:应用程序 1.12 分析和设计 1.12.1 不要迷失: 在整个开发过程中,最重要的事情就是:不要将自己迷失!但事实上这种事情很容易发生。大多数方法都设计用来解决最大范围内的问题。当然,也存在一些特别困难的项目,需要作者付出更为艰辛的努力,或者付出更大的代价。但是,大多数项目都是比较“常规”的,所以一般都能作出成功的分析与设计,而且只需用到推荐的一小部分方法。但无论多么有限,某些形式的处理总是有益的,这可使整个项目的开发更加容易,总比直接了当开始编码好! 也就是说,假如你正在考察一种特殊的方法,其中包含了大量细节,并推荐了许多步骤和文档,那么仍然很难正确判断自己该在何时停止。时刻提醒自己注意以下几个问题: (1) 对象是什么?(怎样将自己的项目分割成一系列单独的组件?) (2) 它们的接口是什么?(需要将什么消息发给每一个对象?) 在确定了对象和它们的接口后,便可着手编写一个程序。出于对多方面原因的考虑,可能还需要比这更多的说明及文档,但要求掌握的资料绝对不能比这还少。 整个过程可划分为四个阶段,阶段0刚刚开始采用某些形式的结构。 1.12.2 阶段0:拟出一个计划: 1.12.3 阶段1:要制作什么?: 1.12.4 阶段2:如何构建? 1.12.5 阶段3:正式创建 1.12.6 阶段4:校订 1.12.7 计划的回报 1.13 Java还是C++? 第2章 一切都是对象 “尽管以C++为基础,但Java是一种更纯粹的面向对象程序设计语言”。 无论C++还是Java都属于杂合语言。但在Java中,设计者觉得这种杂合并不象在C++里那么重要。杂合语言允许采用多种编程风格;之所以说C++是一种杂合语言,是因为它支持与C语言的向后兼容能力。由于C++是C的一个超集,所以包含的许多特性都是后者不具备的,这些特性使C++在某些地方显得过于复杂。 Java语言首先便假定了我们只希望进行面向对象的程序设计。也就是说,正式用它设计之前,必须先将自己的思想转入一个面向对象的世界(除非早已习惯了这个世界的思维方式)。只有做好这个准备工作,与其他OOP语言相比,才能体会到Java的易学易用。在本章,我们将探讨Java程序的基本组件,并体会为什么说Java乃至Java程序内的一切都是对象。 2.1 用句柄操纵对象 2.2 必须创建所有对象: 创建句柄时,我们希望它同一个新对象连接。通常用new关键字达到这一目的。new的意思是:“把我变成这些对象的一种新类型”。所以在上面的例子中,可以说: String s = new String("asdf"); 它不仅指出“将我变成一个新字串”,也通过提供一个初始字串,指出了“如何生成这个新字串”。 当然,字串(String)并非唯一的类型。Java配套提供了数量众多的现成类型。对我们来讲,最重要的就是记住能自行创建类型。事实上,这应是Java程序设计的一项基本操作,是继续本书后余部分学习的基础。 2.2.1 保存在什么地方 2.2.2 特殊情况:主类型 2.2.3 Java中的数组 2.3 绝对不要清除对象:在大多数程序设计语言中,变量的“存在时间”(Lifetime)一直是程序员需要着重考虑的问题。变量应持续多长的时间?如果想清除它,那么何时进行?在变量存在时间上纠缠不清会造成大量的程序错误。在下面的小节里,将阐示Java如何帮助我们完成所有清除工作,从而极大了简化了这个问题。 2.3.1 作用域 2.3.2 对象的作用域 2.4 新建数据类型:类 2.4.1 字段和方法 2.5 方法、自变量和返回值 2.5.1 自变量列表 2.6 构建Java程序:正式构建自己的第一个Java程序前,还有几个问题需要注意。 2.6.1 名字的可见性 2.6.2 使用其他组件 2.6.3 static关键字 2.7 我们的第一个Java程序 2.8 注释和嵌入文档 2.8.1 注释文档 2.8.2 具体语法 2.8.3 嵌入HTML 2.8.4 @see:引用其他类 2.8.5 类文档标记 2.8.6 变量文档标记:变量文档只能包括嵌入的HTML以及@see引用。 2.8.7 方法文档标记 2.8.8 文档示例
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值