背景
继续查缺补漏,充电
1.数组的特点
(1)数组是一种效率最高的存储和随机访问对象引用序列的方式。
(2)数组对象的大小固定,并且在其生命周期不可改变。
(3)可以通过编译器检查,防止插入错误类型和抽取不当类型。
(4)数组标识符其实只是一个引用,指向在堆中创建的一个真实对象,这个(数组)对象
用来保存指向其他对象的引用。
(5)对象数组保存的是引用,基本类型数组直接保存基本类型的值。
2.多维数组
语法如下所示:
int[][] a={ {1,2,3}, {4,5,6}, };
int[][][] a=new int[2][2][4];
Random rand=new Random(47);
int[][][] a=new int[rand.nextInt(7)][][];
for(int i=0;i<a.length;i++){
a[i]=new int[rand.nextInt(5)][];
for(int j=0;j<a[i].length;j++)
a[i][j]=new int[rand.nextInt(5)];
}
3.Arrays
(1)Arrays.deepToString()方法:可以将多维数组转换为多个String。
(2)Arrays.fill()方法:只能用同一个值填充各个位置,对对象而言,只是复制同一个引用。
boolean[] a1=new boolean[size];
Arrays.fill(a1,true);
(3)Arrays.asList()方法:接收任意的序列或数组作为参数,将其转变为List容器。
4.复制数组
System.arraycopy() 不会执行自动包装和自动拆包。
5.数组比较
Arrays类提供了重载后的equals方法,用来比较整个数组。
6.数组元素的比较
(1)实现Comparable接口,重写compareTo()方法。
使用Arrays.sort()方法进行比较
package arrays;
import java.util.*;
import tools.*;
import static tools.Print.*;
public class CompType implements Comparable<CompType> {
int i;
int j;
private static int count=1;
public CompType(int n1,int n2){
i=n1;
j=n2;
}
public String toString(){
String result="[i= "+i+",j="+j+"]";
if(count++%3==0)
result +="\n";
return result;
}
public int compareTo(CompType rv){
return (i<rv.i?-1:(i==rv.i?0:1));
}
private static Random r=new Random(47);
public static Generator<CompType> generator(){
return new Generator<CompType>(){
public CompType next(){
return new CompType(r.nextInt(100),r.nextInt(100));
}
};
}
public static void main(String[] args){
CompType[] a=new CompType[10];
Generator<CompType> n= CompType.generator();
for(int i=0,j=a.length;i<j;i++)
a[i]=n.next();
print(Arrays.toString(a));
Arrays.sort(a);
print(Arrays.toString(a));
}
}
使用Arrays.sort(a,Collections.reverseeOrder()) 来反转自然的排序顺序。Collection类的reverseOrder()方法
会产生一个Comparator。
(2)创建实现Comparator接口的单独的类。接口有compare()和equals()方法。一般不实现equals(),除非有特
殊的性能需求。
package arrays;
import java.util.*;
import tools.*;
import static tools.Print.*;
class CompTypeComparator implements Comparator<CompType>{
public int compare(CompType o1,CompType o2){
return (o1.j<o2.j?-1:(o1.j==o2.j)?0:1);
}
}
public class ComparatorTest {
public static void main(String[] args){
CompType[] a=new CompType[10];
Generator<CompType> n= CompType.generator();
for(int i=0,j=a.length;i<j;i++)
a[i]=n.next();
Arrays.sort(a,new CompTypeComparator());
print(Arrays.toString(a));
}
}
7.数组排序
使用内置的排序方法,可以对任意的基本类型数组排序;对任意的对象数组排序,
只要该对象实现了Comparable接口或具有相关联的Comparator。
想忽略大小写字母将单词都放在一起排序,可以使用String.CASE_INSENSITIVE_ORDER
Arrays.sort(sa,String.CASE_INSENSITIVE_ORDER)
针对基本类型采用“快速排序”,针对对象用“稳定归并排序”。
8.在已排序的数组中查找
如果数组已经排序,用Arrays.binarySearch()。
如果使用了Comparator排序了某个对象数组(基本类型数组无法使用Comparator进行排序),
在使用binarySearch()时必须提供同样的Comparator。
9.数据生成器
下面采用了策略设计模式,每个不同的Generator都表示一个不同的策略
package tools;
public class CountingGenerator {
public static class Boolean implements Generator<java.lang.Boolean>{
private boolean value=false;
public java.lang.Boolean next(){
value=!value;
return value;
}
}
public static class Byte implements Generator<java.lang.Byte>{
private byte value=0;
public java.lang.Byte next(){return value++;}
}
static char[] chars=("abcdefghijklmnopqrstuvwxyz"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ").toCharArray();
public static class Character implements Generator<java.lang.Character>{
int index =-1;
public java.lang.Character next(){
index=(index+1)%chars.length;
return chars[index];
}
}
public static class String implements Generator<java.lang.String>{
private int length=7;
Generator<java.lang.Character> cg=new Character();
public String(){}
public String(int length){ this.length=length;}
public java.lang.String next(){
char[] buf=new char[length];
for(int i=0;i<length;i++)
buf[i]=cg.next();
return new java.lang.String(buf);
}
}
public static class Short implements Generator<java.lang.Short>{
private short value=0;
public java.lang.Short next(){ return value++;}
}
public static class Integer implements Generator<java.lang.Integer>{
private int value=0;
public java.lang.Integer next(){ return value++;}
}
public static class Float implements Generator<java.lang.Float>{
private float value=0;
public java.lang.Float next(){
float result=value;
value+=1.0;
return result;
}
}
public static class Double implements Generator<java.lang.Double>{
private double value=0.0;
public java.lang.Double next(){
double result=value;
value+=1.0;
return result;
}
}
}
可以利用反射来测试Generator的任何集合,例如:
import tools.*;
public class GeneratorsTest {
public static int size=10;
public static void test(Class<?> surroundingClass){
for(Class<?> type:surroundingClass.getClasses()){
System.out.print(type.getSimpleName()+":");
try{
Generator<?> g=(Generator<?>)type.newInstance();
for(int i=0;i<size;i++)
System.out.printf(g.next()+" ");
System.out.println();
}catch(Exception e){
throw new RuntimeException(e);
}
}
}
public static void main(String[] args){
test(CountingGenerator.class);
}
}
下面试转换器,可以接受任意包装器对象数组,然后转化成相应的基本类型数组:
package tools;
public class ConvertTo {
public static boolean[] primitive(Boolean[] in){
boolean[] result=new boolean[in.length];
for(int i=0;i<in.length;i++)
result[i]=in[i];
return result;
}
public static char[] primitive(Character[] in){
char[] result=new char[in.length];
for(int i=0;i<in.length;i++)
result[i]=in[i];
return result;
}
public static byte[] primitive(Byte[] in){
byte[] result=new byte[in.length];
for(int i=0;i<in.length;i++)
result[i]=in[i];
return result;
}
public static short[] primitive(Short[] in){
short[] result=new short[in.length];
for(int i=0;i<in.length;i++)
result[i]=in[i];
return result;
}
public static int[] primitive(Integer[] in){
int[] result=new int[in.length];
for(int i=0;i<in.length;i++)
result[i]=in[i];
return result;
}
public static long[] primitive(Long[] in){
long[] result=new long[in.length];
for(int i=0;i<in.length;i++)
result[i]=in[i];
return result;
}
public static float[] primitive(Float[] in){
float[] result=new float[in.length];
for(int i=0;i<in.length;i++)
result[i]=in[i];
return result;
}
public static double[] primitive(Double[] in){
double[] result=new double[in.length];
for(int i=0;i<in.length;i++)
result[i]=in[i];
return result;
}
}
总结
优选容器而不是数组,只有在已证明性能成为问题时,才应该将程序重构为使用数组。