读改善java程序的151个建议(6)
来源:互联网 发布:苹果手机壁纸软件排行 编辑:程序博客网 时间:2024/05/18 02:24
60.性能考虑,数组是首选
在性能要求比较高的场景中考虑使用数组替代集合。
61.若有必要,使用变长数组
java中的数组是定义的,一旦经过初始化声明就不可改变长度,这在实际使用中非常不方便。
事实上,可以通过对数组扩容“婉转”地解决该问题
例如:
public static < T> T[] expandCapacity( T[] datas, int newLen ){
newLen= newLen<0?0: newLen;
return Arrays .copyOf( datas, newLen);
}
62.警惕数组的浅拷贝
这里说的是数组中的元素没有实现Serializable接口,但是通过copyOf方法产生的数组是一个浅拷贝,这与序列化的浅拷贝完全相同。
也就是:基本类型是直接拷贝值,其他都是拷贝引用地址。需要说明的是,数组的clone方法也是与此相同的,同样是浅拷贝,而且集合的clone方法也都是浅拷贝,需要在拷贝时多留心了
63.在明确的场景下,为集合指定初始容量
这里首先说的是针对ArrayList,在使用的时候,如果场景确定,比如一个班的学生,一般也都是50个左右。在初始化时,可直接指定ArrayList的长度为50*1.5=75,为什么是1.5?查看ArrayList的add方法中的ensureCapacity方法,源码如下:
public void ensureCapacity ( int paramInt) {
this .modCount += 1;
int i = this .elementData. length;
if ( paramInt <= i)
return ;
Object [] arrayOfObject = this.elementData ;
int j = i * 3 / 2 + 1;
if (j < paramInt)
j = paramInt;
this .elementData = Arrays .copyOf( this. elementData, j);
}
源码中扩容1.5倍+1,这种方式最极端的情况也就是浪费1/3,比2.5或3.5位扩容浪费少。
源码中elementData的默认长度是10,也就是说,在我们不指定ArrayList容量的情况下,默认声明的ArrayList容量是10
Vector扩容与ArrayList有点不同:源码如下:
private void ensureCapacityHelper ( int paramInt) {
int i = this .elementData. length;
if ( paramInt <= i)
return ;
Object [] arrayOfObject = this.elementData ;
int j = (this .capacityIncrement > 0) ? i + this .capacityIncrement
: i * 2;
if (j < paramInt)
j = paramInt;
this .elementData = Arrays .copyOf( this. elementData, j);
}
Vector提供了一个递增步长(capacityIncrement变量),不设此值,则是容量翻倍,设置了的话,则是每次要增加的长度。
其他集合,如HashMap是按照倍数增加的,Stack继随自Vector,所以采用的是与其相同的扩容原则。
64.多种最值算法,适时选择
这里主要针对求集合的一些最值,例如最大值,最小值,第二最大值等类似的情况下。
虽然我们可以自己写冒泡算法,或是将集俣先sort一下,再直接取出来,但还可以利用集合之间的转换来实现
例如:取出一个班组的第二高分:
public static int getSecond( Integer[] data){
List< Integer> dataList= Arrays .asList( data);
TreeSet <Integer > ts= new TreeSet< Integer>(dataList);
return ts.lower (ts.last ());
}
//test
Integer [] testArr=new Integer[]{22,45,12,122,542,542,345,22};
int second=getSecond(testArr);
System .out.println (second);
由于数组不能直接剔除重复数据,但Set集合却是可以的,而且Set的子类TreeSet还能自动排序,所以通过上面的getSecond方法,即可得出结果。
总之一句话:最值计算时使用集合最简单,使用数组性能最优。
65.避开基本类型数组转换列表陷阱
这里主要说的就是Arrays.asList方法,需要特别注意,原始类型数组不能做为asList的输入参数,否则会引起程序逻辑混乱。
Arrays.asList的方法说明:输入一个变长参数,返回一个固定长度的列表。
源码如下:
public static < T> List< T> asList( T[] paramArrayOfT ) {
return new ArrayList (paramArrayOfT );
}
由于基本类型是不能泛型化的,也就是说8个基本类型不能作为泛型参数,要想作为泛型参数就必须使用其所对应的包装类型,那下面的例子:
int data[]={1,2,3,4,5};
List list2=Arrays .asList (data);
System .out.println ("列表中元素数量是:" +list2.size()); //结果是1
System .out.println ("元素类型是:" +list2.get(0).getClass()); //class [I
为什么没有编译报错?
在java中,数组是一个对象,它是可以泛型化的,也就是说我们的例子是把一个int类型的数组作为了T的类型,所以转换后在List中就只有一个类型为int数组的元素了。
之所以打印出"class [I" 是因为Array是属于java.lang.reflect包的,它是通过反射访问数组元素的工具类,在java中任何一个数组的类都是"[I",究其原因是就是Java并没有定义数组这一个类,它是在编译的时候生成的,是一个特殊的类。
所以只需将例子中的数组修正为包装类型即可。
66.asList方法产生的List对象不可更改
这是因为Arrays.asList中生成的ArrayList类(源码见上面65),并非java.utils.ArrayList,而是java.utils.Arrays工具类的一个内置类。也没有提供add方法。
所以除非你的list只用于只读,否则需要特别注意通过Arrays.asList生成的list对象
0 0
- 读改善java程序的151个建议(6)
- 《改善Java程序的151个建议》
- 改善java程序的151个建议
- 读改善java程序的151个建议(1)
- 读改善java程序的151个建议(2)
- 读改善java程序的151个建议(3)
- 读改善java程序的151个建议(4)
- 读改善java程序的151个建议(5)
- 读改善java程序的151个建议(7)
- 读改善java程序的151个建议(8)
- 《编写高质量代码:改善Java程序的151个建议》 建议6
- 改善Java程序的151个建议笔记
- 改善java程序的151个建议 读后感一
- 改善java程序的151个建议 读后感二
- 改善java程序的151个建议 读后感三
- 改善java程序的151个建议 读后感四
- 改善java程序的151个建议 读后感五
- 改善java程序的151个建议--笔记一
- (Google面试题)有四个线程1、2、3、4。线程1的功能就是输出1,线程2的功能就是输出2,以此类推.........现在有四个文件ABCD。初始都为空
- 坑爹的后台http请求失败网页请求却可以
- 机器学习领域的框架、库以及软件
- 【Bootstrap】html属性顺序的编码规范及表单
- c# 彩色图片变为黑白图片
- 读改善java程序的151个建议(6)
- freemarker生成excel、word、html、xml实例教程
- Cocos2d-x v3.0物理系统 利用PhysicsEditor创建多边形
- IOS开发---OC语言-㉘内存管理ARC循环调用
- Note: LSR LER
- 『IOS』大屏iPhone的适配
- 机器学习资源指南
- ListPreference 基本使用
- expected specifier-qualifier-list before 'size_t'