优雅编程之这样设计通用程序,你就“正常”了(二十七)

开心一笑

【1.别人复习都是无懈可击,学渣复习是无中生有;
2.好了老师,我们各退一步,你们别讲了,我们也不听了;
3.少一点作业,多一颗数木;少一次考试,多一片森林;保护环境人人有责......】

提出问题

项目中如何编写通用程序???

解决问题

励志图片

以下来自《Effective Java》中的读书笔记:

将局部变量的作用域最小化

要是局部变量的作用域最小化,最有力的方法就是在第一次使用它的地方申明。
几乎每个局部变量的声明,都应该包含一个初始化表达式。

下面是一种对局部变量的作用域进行最小化的循环做法。

例如:

//防止每次循环都去调用size方法,提高性能
for(int i=0,len = userList.size();i < len;i++){
    .....
}

最后一种将局部变量的作用域最小化的方法是使方法小而集中。(这个在之前的文章中已经多次提到了)

for-each循环优于传统的for循环

例如:

//不推荐
for(Iterator i=c.iterator();i.hasNext()){
    doSomething(i.next());
}
//推荐    
for(Element e:c){
    doSomething(e);
}

有三种情况无法使用for-each循环:

  • 过滤:如果需要遍历集合。并删除选定的元素,就需要使用显示的迭代器,以便可以调用它的remove方法。
  • 转换:如果需要遍历列表或者数组,并取代部分或者全部的元素值,就需要列表迭代器或者数组索引,以便设定元素的值。
  • 平行迭代:如果需要并行的遍历多个集合,就需要显示的控制迭代器或者索引变量,以便所有迭代器或者索引变量都可以得到同步迁移。
了解和使用类库

尽可能的使用第三方类库。通过使用标准类库,可以充分利用这些编写标准类库的专家的知识,以及在你之前的其他人的使用经验。

例如:

org.apache.commons.lang3

总而言之,不要重新发明轮子,如果你要做的事情看起来是十分常见的,有可能类库中已经有某个类完成了这样的工作,如果确实是这样,就使用现成的。如果还不清楚是否存在这样的类,就去查一查。

如果需要准确的答案,请避免使用float和double

float和double类型不适合用于货币计算,解决办法是使用BigDecimal,int和long进行货币计算。

总而言之,对于任何需要精确答案的计算任务,请不要使用float或者double。

基本类型优先于装箱基本类型

基本类型:int,double,boolean等等
引用类型:String和List等等
装箱基本类型:Integer,Double和Boolean等等

例如:

static Integer i;
public static void main(String[] args) {
    //自动拆箱,报NullPointerException异常
    if(i == 42){
        System.out.println("unbelievable");
    }
}

当在一项操作中混合使用基本类型和装箱基本类型时,装箱基本类型就会自动拆箱,这种情况无一例外。

上面问题就是修正i为int类型就好了。

例如:

//这个程序存在性能问题
public static void main(String[] args) {
    Long sum = 0L;
    for(long i=0;i<Integer.MAX_VALUE;i++){
        //变量被反复的装箱和拆箱,导致性能问题
        sum += i;
    }
    System.out.println(sum);
}

那么什么时候应该使用装箱基本类型呢?

  • 第一个是作为集合中的元素,键和值。
  • 第二个是在参数化类型中,必须使用装箱基本类型作为类型参数。

总之,当可以选择的时候,基本类型要优先于装箱基本类型。基本类型更加简单,也更加快速,如果必须使用,装箱基本类型要特别小心。自动装箱减少了使用装箱基本类型的繁琐性,但是并没有减少它的风险。当程序用 == 操作符比较两个装箱基本类型时。他做了个同一性比较,这几乎肯定不是你所希望的。当程序进行涉及装箱和拆箱基本类型的混合类型计算时,他会进行拆箱。当程序进行拆箱时,会抛出空指针异常。最后当程序装箱了基本类型值时,会导致高开销和不必要的对象创建。

如果其它类型更适合,则尽量避免使用字符串
  • 字符串不适合代替其他的值类型,数值类型应当被适当地转换为数值类型,比如int,float或者double,布尔类型就应该被转化为boolean类型等等。
  • 字符串不适合代替枚举类型。

例如:

String compounKey = className + "#" + i.next();

缺点:如果用来分隔的字符也出现在某个域中,结果就会出现混乱。

  • 字符串不适合代替聚集类型。(不可伪造的键有时候被称为能力)

例如:

    //有问题,在线程中,如果客户传入key相同,安全性就很差
    public static set(String key,Object value){
    
    }

    public static Object get(String key){
    
    }

改正:

    public static class Key{
        Key(){}
    }

    public static Key getKey(){
        return new Key();
    }
    //重点在这里哦,使用对象Key哦
    public static void set(Key key,Object value);

    public static Object get(Key key);
当心字符串连接的性能

对于大规模的场景中,为连接n个字符串而重复的使用字符串连接操作符,需要n的平方级的时间。

具体的详细内容,请看之前的这篇文章:

优雅编程之这样考虑字符性能,你就“正常”了(二十二)

通用接口引用对象

例如:

//正确
List<Subscribe> subscribes = new Vector<>();

//欠缺
Vector<Subscribe> subscribes = new Vector<>();

当你决定更换实现时,所要做的就只是改变构造器中类的名称。

List<Subscribe> subscribes = new ArrayList<>();

周围的所有代码都可以继续工作。

但是

如果没有合适的接口存在,完全可以用类,而不是接口来引用对象。例如考虑值类,比如String和BigInteger。记住,值类很少会用多个实现编写。它们通常是final
类实现了接口,但是它提供了接口中不存在的额外方法,如果程序依赖于这些额外的方法,这种类就应该只被用来引用它的实例,它很少应该被用作参数类型。

接口优先于相射机制

反射机制需要付出代价:

  • 丧失了编译时类型检查的好处:如果程序企图用反射方式调用不存在或不可访问的方法,在运行时它将会失败。
  • 执行反射访问所需要的代码非常笨拙和冗长。
  • 性能损耗。反射方法调用的比普通方法调用慢了很多。

通常普通应用程序在运行时不应该以反射方式访问对象。

谨慎地使用本地方法

Java Native Interface(JNI)允许Java程序可以调用本地方法(native method)

使用本地方法来提高性能的做法不值得提倡。

使用本地方法有一些严重的缺点。因为本地语言不是安全的

谨慎的进行优化

有三条与优化相关的格言是每个人都应该知道的。

很多计算机上的过失都被归咎于效率(没有必要达到的效率),而不是任何其他的原因,甚至包括盲目地做傻事。
不要去计较效率上的一些小小的得失,在97%的情况下,不成熟的优化才是一切问题的根源。
在优化方面,我们应该遵守2条原则:1.不要进行优化。2.(仅针对专家)还是不要进行优化,也就是说,在你还没有绝对清晰的未优化方案之前,请不要进行优化。

总之,不要费力去编写快速程序,应该努力编写好的程序,速度自然会随之而来。

普遍接受的命名惯例
  • 包名称:一个或者多个包的简短名称组成,每个简短名称通常不超过8个字符(事实发现,JDK上的包也些也超过8个字符:java.awt.datatransfer )。所以作者在这里使用通常,也就是有例外

    java.applet
    java.awt
    java.awt.color

  • 类和接口名称,包括枚举和注解名称:通常由一个或者多个单词组成,每个单词的首字母大写(TimerTask),尽量避免缩写,除非类似这种:max或者min

  • 方法和域的名称:与类和接口名称类似,只是方法首字母小写。方法的名称一般由动词或者动词,名称组成。如:remove,removeUser等等

  • 常量:如:public static final int MIN_VALUE,全部大写,中间用下划线分割

  • 局部变量名称与成员变量的名称类似,只不过它允许缩写

  • 类型参数名称:通常由单个字母组成,T表示任意类型,E表示集合元素类型,K,V表示键和值,X表示异常

读书感悟

来自《邻室的音乐》

  • 穷是一种心态,你若一辈子坚持自己是穷人,拥有大量金钱也救不了你。
  • 凡是太好的东西都不像真的。又有人说,如果一件事好得不似真的,可能它的确不是真的。
  • 人生试题一共四道题目。学业事业婚姻家庭,平均分高才能及格,切莫花太多时间在任何一题上。
  • 真正聪明的女子该是懂得利用自己的智慧享受生命,而不仅仅是为了那点生不带来死不带去的利益。这点没有想通,便失去了自我,失去了珍贵的友谊。

其他

如果有带给你一丝丝小快乐,就让快乐继续传递下去,欢迎转载,点赞,顶,欢迎留下宝贵的意见,多谢支持!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,598评论 18 139
  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 10,865评论 6 13
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,577评论 18 399
  • 1.关于RabbitMQ## RabbitMQ是一个开源的消息代理和队列服务器,用来通过普通协议在完全不同的应用之...
    _既白_阅读 10,692评论 5 18
  • 儿子,业余时间能成就一个人,也能毁灭一个人,人的成就和差异有时就取决于业余时间。每个人在校时间学习都差不多,更重要...
    听雨聆声阅读 2,474评论 2 7