开心一笑
【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表示异常
读书感悟
来自《邻室的音乐》
- 穷是一种心态,你若一辈子坚持自己是穷人,拥有大量金钱也救不了你。
- 凡是太好的东西都不像真的。又有人说,如果一件事好得不似真的,可能它的确不是真的。
- 人生试题一共四道题目。学业事业婚姻家庭,平均分高才能及格,切莫花太多时间在任何一题上。
- 真正聪明的女子该是懂得利用自己的智慧享受生命,而不仅仅是为了那点生不带来死不带去的利益。这点没有想通,便失去了自我,失去了珍贵的友谊。
其他
如果有带给你一丝丝小快乐,就让快乐继续传递下去,欢迎转载,点赞,顶,欢迎留下宝贵的意见,多谢支持!