基础知识
很多道理往往可以用简单的话说明白。关于Java数组,你只需要记住两句话:
1.数组是相同类型数据的有序集合;
2.数组也是对象。
展开说说:
- 长度确定且不可改;
- 类型不可改;
- 类型可基本可引用;
- 数据的变量属于引用类型,数组也是对象,数据的元素相当于对象的属性。
Java数组初始化的三种方式:
- 静态初始化:一开始就把值给好了;
- 动态初始化:一开始给个长度,然后再逐个赋值;
- 默认初始化:动态初始化前一步,然后就用这个系统默认给的值:0、0.0、false、null。
练习点:
- Array.toString([]);
- System.arraycopy(原数组,原数组开始的索引,要拷贝到的数组,目标数组开始拷贝的索引,从原数组拷贝的长度);
- for(typei:array)来逐个遍历;
- 三种初始化方法;
练习代码如下:
publicclassCopyArray{publicstaticvoidmain(String[]args){String[]companies=newString[]{"alibaba","bytedance","pinduoduo","dingdong","souhu"};String[]copy2=newString[3];System.arraycopy(companies,0,copy2,0,3);for(Strings:copy2){System.out.println(s);}}}/**结果:*alibaba*bytedance*pinduoduo*/
publicclassTest02{publicstaticvoidmain(String[]args){//静态初始化要在声明后直接初始化。Manm=newMan(20,"SuperKris");//Man[]mans=newMan[6];这一行相当于没有用了Man[]mans=newMan[]{newMan(10,"Kris0"),newMan(11,"Kris1"),newMan(13,"Kris3"),newMan(12,"Kris2"),newMan(15,"Kris5"),};mans[4]=m;for(inti=0;i<mans.length;i++){System.out.println(mans[i].getName());}//增强for循环,把每一个元素取出来,放给这个变量。for(Manman:mans){System.out.println(man);}}}classMan{privateintid;privateStringname;publicMan(){}publicMan(intid,Stringname){this.id=id;this.name=name;}@OverridepublicStringtoString(){return"id="+id+",name="+name;}//省略了JavaBean()}
publicclassTest03{publicstaticvoidmain(String[]args){int[]a={100,200,300};int[]b={1,2,3,4234,22,45,765};System.out.println(Arrays.toString(a));Arrays.sort(b);System.out.println(b.toString());//二分查找System.out.println("b:"+Arrays.toString(b));//存在的话,就返回索引System.out.println("该元素的索引是:"+Arrays.binarySearch(b,22));//这个数不存在的话,返回负数System.out.println("该元素的索引是:"+Arrays.binarySearch(b,555));//把b从fromIndex,到toIndex-1对应的位置,复制为最后一个参数[)区间一般都是左开右闭Arrays.fill(b,0,3,500);System.out.println(Arrays.toString(b));}}
运行结果如下图:
查看源码的技巧:
在IDEA里按住Alt/command键,然后鼠标悬在想看的地方就可以访问到
有两个要注意的地方:
1.Array.toString()和之前String里,Object里的toString不一样。
这个是普通的toString方法:
publicStringtoString(){returngetClass().getName()+"@"+Integer.toHexString(hashCode());}复制代码
这个是Array.toString()的源码,是有参数的,而且声明了static:
publicstaticStringtoString(int[]a){if(a==null)return"null";intiMax=a.length-1;if(iMax==-1)return"[]";StringBuilderb=newStringBuilder();b.append('[');for(inti=0;;i++){b.append(a[i]);if(i==iMax)returnb.append(']').toString();b.append(",");}}
2.为什么自带的二分法,如果一个数找不到,返回的索引是-6呢?
这个时候我们就可以去看一眼源码一窥真相。
二分查找的源码:
privatestaticintbinarySearch0(int[]a,intfromIndex,inttoIndex,intkey){intlow=fromIndex;inthigh=toIndex-1;while(low<=high){intmid=(low+high)>>>1;intmidVal=a[mid];if(midVal<key)low=mid+1;elseif(midVal>key)high=mid-1;elsereturnmid;//keyfound}return-(low+1);//keynotfound.}
然后你就会发现在最后一行:没找到的话,默认取了左边最靠近的索引+1,再取负数。
而且还有一个地方非常的细节,二分法取中间的话,源码用了位移的操作,没有写公式,有效地防止了溢出。