Thinking In Java----2017.1.22 数组

1.由于泛型和包装机制的出现,数组目前硕果仅存的优势就是效率(以前是解决存储基本类型序列的好的选择):数组是一种效率最高的存储和随机访问对象引用序列的方式。

 

2.数组标识符其实就是一个引用,它指向了在堆中的一个真实的数组对象,这个数组对象保存指向其他对象的引用。

 

 

3.Arays.deepToString():它可以将多维数组转换为多个String

 

4.粗糙数组:数组中构成矩阵的每个向量都可以有不同的长度。

 

5.Integer[][]a ;

a =new Integer[3][];//一维长度定义完毕

for(int i=0;i<a.length;i++){

a[i] = new Integer[10];

//定义了二维长度。

for(int j=0;j<a[i].length;j++){

//二维数组中的每一项

a[i][j] = i*j;

}

}

[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]]

 

 

Integer[][][]a ;

a =new Integer[3][][];//一维长度定义完毕

for(int i=0;i<a.length;i++){

a[i] = new Integer[2][];

for(int j=0;j<a[i].length;j++){

a[i][j] = new Integer[3];

for(int x=0;x<a[i][j].length;x++){

a[i][j][x] = j*x;

}

}

}

 

 

System.out.println(Arrays.deepToString(a));

}

 

 

[[[0, 0, 0], [0, 1, 2]], [[0, 0, 0], [0, 1, 2]], [[0, 0, 0], [0, 1, 2]]]

 

 

体会下维度,只有在最后一个维度的真正的赋值(2维就是a[i][j]赋值,a[i]代表二维数组,三维就是a[i][j][k],a[i]代表二维数组,a[i][j]代表三维数组,最后a[i][j][k]用于赋值)。

 

 

 

 

 

 

6.数组与泛型:

 

a.)你不能实例化”具有”泛型化的数组,但是你可以泛型化数组本身的类型:

//Illegal

new A<what>[10];(如下所示,new T[]也不行,也是因为擦除)

擦除会移除参数类型信息,而数组必须知道他们所持有信息的确切类型,以强制保证类型安全。

 

Class A<T>{

T[] array;

Public static<T>T[]f(T[] t,int size){return t}

如上,但是我们可以泛型化数组本身的类型。

 

这里应该注意的是,你不能创建泛型数组!!!:

假如在方法里是{

array = new T[size];//这里就犯错了,因为创建的时候类型被擦除,此时类型为未知,你创建不了类型未知的数组,如果创建的是Object数组,再转型,就可以了,因为Object数组可以包含除了基本类型外的所有类型。

}

}

b.)但是它允许创建泛型数组引用:

A<What>[] a;

尽管你不能创建实际的泛型数组,但是你可以创建非泛型数组,然后强制转型为泛型数组;

List<String>[] example;

List[] l = new List[10];

example = (List<String>[])l;

 

 

 

c.)数组是可协变类型的:

List[]l =new ArrayList[10];

Object[]object =l;

 

ArrayList[]b  =new ArrayList[10];

List[]test =b;

 

如上,数组可以很自然的转换到其父类类型的数组。

 

 

7.Arrays.fill(数组,值):这个方法的作用十分有限,它只能用同一个值填充数组的各个地方。

 

 

8.关于JAVA中的math.round :不能完全等同是四舍五入,其实有规律的:参数的小数点后一位,大于五全部加,等于五正数加,小于五全不加。(这里的全是指正数和负数情况)

 

 

9.Arrays实用功能:

以下所有方法都是Arrays.xxx

a.) equals(数组a,数组b)用于比较两个数组是否相等。

 

 

 

(数组本身没有equals方法,但是因为Java中所有的类都继承Object,所以他调用的是Object的equals方法,这个equals方法的声明是:
public boolean equals(Object obj) {
return (this == obj);
}
所以说你做的比较是比较两个数组的
内存地址,所以是false)
如果你要比较着两个数组的内容的话,可以这样写 Arrays.equals(ch,c)

 

Arrays.equals()比较的是内容,数组本身没有equals,但是所有类继承自Object,所以调用的是Object的equals()。比较的是内存地址

 

b.)deepEquals()用于多维数组;

c.)fill()在数组中的每个位置填上同一个值;

d.)sort()用于数组排序;

e.)binarySearch()用于在排序后的数组中查找元素;(数组要使用二分查找法必须先排序才可以)

f.)toString();

g.)hashCode()产生数组的散列码。

 

 

 

 

10.复制数组System.arrayCopy(源数组,源数组开始位置,目标数组,目标数组开始位置,复制长度):

 需要知道的有:

用它复制数组比for循环赋值数组快的多。

也可以复制对象,但是复制对象的时候复制的是对象的引用--成为”浅复制”

这个方法不会执行自动包装和自动拆包,所以源数组和目标数组必须具有相同的确切类型。

Integer[]a  =new Integer[]{new Integer(5),new Integer(2),new Integer(3),new Integer(10)};

Integer[]b =new Integer[7] ;

System.arraycopy(a, 0, b, 0,a.length);

System.out.println(Arrays.toString(b));

 

 

 

 

 

 

11.数组元素的比较:

第一种方式,如果你自定义了一个数组,你想让你的数组元素有比较的能力,即可以应用于Arrays.sort()方法中,那么你应该让你数组中的类实现Comparable接口,这会强制你实现compareTo()方法,例子如下:

 

public static void main(String[]args) {

A[]a = {

new A(),new A(),new A(),new A(),new A()

};

 

System.out.println(Arrays.deepToString(a));

 

System.out.println("排序后");

 

Arrays.sort(a);

 

System.out.println(Arrays.deepToString(a));

}

 

}

 

class Aimplements Comparable<A>{

Random rand =new Random();

int i =rand.nextInt(20);

@Override

public int compareTo(Ao) {

return (i < o.i ? -1 : (i==o.i? 0 : 1));

}

 

 

public String toString(){

return " "+i;

}

}

 

在compareTo()方法中,如果当前值小于比较值,返回负值; 如果相等,返回0;如果大于,返回正值。

 

如果你没用实现Comparable接口,调用sort()的时候ClassCastException运行时异常。因为sort()需要把参数的类型转换为Comparable。

 

 

 

 

问题:如果你的一个类没有实现Comparable,或者已经实现Comparable,但是你不喜欢它的排序方式,那么怎么办?

 

 

 

 

第二种方式:用系统已有的 或者 自己生成自己的Comparator。

 

 

 

public static <T> void sort(T[] a,Comparator<? super T> c)

请看,方法的第二个参数,是通过Comparator进行比较的。

 

a.)Collections.reverseOrder()方法产生一个倒序的Comparator,如下:

public static void main(String[]args) {

A[]a = {

new A(),new A(),new A(),new A(),new A()

};

 

System.out.println(Arrays.deepToString(a));

 

System.out.println("排序后");

 

//Arrays.sort(a);

Arrays.sort(a,Collections.reverseOrder());

System.out.println(Arrays.deepToString(a));

}

 

}

b.)你也可以定义自己的Comparator:

 

 

public static void main(String[]args) {

A[]a = {

new A(),new A(),new A(),new A(),new A()

};

 

System.out.println(Arrays.deepToString(a));

 

System.out.println("排序后");

 

//Arrays.sort(a);

//Arrays.sort(a,Collections.reverseOrder());

 

Arrays.sort(a,new AComparator());

System.out.println(Arrays.deepToString(a));

}

 

}

 

class A {

Randomrand =new Random();

int i =rand.nextInt(20);

//@Override

//publicint compareTo(A o) {

//return (i<o.i?-1:(i==o.i?0:1));

//}

 

public String toString(){

return " "+i;

}

}

 

class AComparatorimplements Comparator<A>{

 

@Override

public int compare(Ao1, Ao2) {

return (o1.i<o2.i?-1:(o1.i==o2.i?0:1));

}

 

}

 

 

 

 

 

关于字符串的排序需要注意的地方:

 

String排序算法根据词典编排序,大写字母放在前面输出,然后才是小写字母,如果你希望忽略大小写,可以sort(String s,String.CASE_INSENSITIVE_ORDER);

 

总结:只要我们要比较的对象实现了Comparable或者我们有相关的Comparator,那么我们就可以进行数组元素的比较。Java中默认对基本类型进行快速排序,对对象进行稳定归并排序。

 

 

 

12.在已经排序的数组中查找元素:

如果找到了目标,Arrays.binarySearch()产生的返回值等于或者大于0;

 

 

public static void main(String[]args) {

Aa3 =new A(7);

A[]a = {

new A(3),new A(5),a3,new A(10),new A(11),new A(2),new A(6)

};

 

System.out.println(Arrays.deepToString(a));

 

System.out.println("排序后");

 

//Arrays.sort(a);

//Arrays.sort(a,Collections.reverseOrder());

 

Arrays.sort(a,new AComparator());

System.out.println(Arrays.deepToString(a));

System.out.println(Arrays.binarySearch(a,a3,new AComparator()));

}

 

}

 

class A {

int i;

 

 A(int i ){

this.i =i;

}

public String toString(){

return " "+i;

}

}

 

class AComparatorimplements Comparator<A>{

 

@Override

public int compare(Ao1, Ao2) {

return (o1.i<o2.i?-1:(o1.i==o2.i?0:1));

}

 

}

 

 

[ 3,  5,  7,  10,  11,  2,  6]

排序后

[ 2,  3,  5,  6,  7,  10,  11]

4

 

注意:如果用Comparator排序了某个对象数组,在使用binarySearch()的时候你需要提供你的Comparator。

Arrays.binarySearch(a,a3,new AComparator())

第一个参数是目标数组,第二个是目标,第三个你的比较器。

如果数组中有重复的元素,无法保证最终找到的是这点些副本中的哪一个,如果需要对没有重复元素的数组排序,可以使用TreeSet和LinkedHashSet。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值