目录
三.数组
数组的基本概念
数组的定义
数组的使用
数组的遍历及排序
数组是引用数据类型
初始JVM的内存分布
基本类型变量和引用类型变量的区别
认识null
数组的应用场景
数组练习
数组转字符串
数组拷贝
这里给了另一种方法(也可以当成扩容)
JVM其实就是C/C++写的,所以究其底层,我们还可以这么做:(支持部分拷贝)
查找数组中指定元素
二维数组
数组中存放的元素其数据类型相同。数组的空间是连在一起的,每个空间都有自己的编号。编号又叫下标或索引,起始编号为0。
数组是引用数据类型,所以创建时得加new,可以简写
public class HelloWorld {
public static void main(String[] args) {
int[] arr0 = {1,2,3,4};
int[] arr1 = new int[]{1,2,3,4,5}; //静态初始化
int[] arr2 = new int[10]; //只是分配了内存,没有初始化,默认是0
// int[] arr3 = new int[2]{1,2}; //这种也是错误的,在等号后面,要么中括号里有数字,要么花括号里有数字
//一般通过new关键字 实例化对象。Java中的数组其实就是一个对象,Java中一切皆对象
double[] score = new double[5];
String[] name = new String[]{"I","love","study","!"};
}
}
可以通过System.out.println(arr0.length);来实现求数组长度
import java.util.Arrays;
public class HelloWorld {
public static void main(String[] args) {
int[] arr0 = {1,21,3,14};
for (int i = 0; i < arr0.length; i++)
System.out.print(arr0[i]);
System.out.println();
for (int x : arr0)
System.out.print(x); //依次输出1 21 3 14
System.out.println();
String str = Arrays.toString(arr0);
System.out.println(str); //以字符串形式输出[1, 21, 3, 14]
Arrays.sort(arr0);
System.out.println(str); //以字符串形式输出[1, 21, 3, 14]
}
}
JVM对所使用的内存按功能的不同进行了划分
关于这段代码,输出arr0的地址
public class HelloWorld { public static void main(String[] args) { int[] arr0 = {1,21,3,14}; System.out.println(arr0); } }输出结果为:[I@1b6d3586
[ 代表这是一个数组,I 表示数组类型是整形,@作为分割,后面是16进制的数字,这个16进制数字暂且可以看成数组
方法区和堆属于线程共享的区域,其他的是线程隔离的区域。
引用变量,其实就是一个变量来存地址。(没有首地址的概念)。空间中存的是对象所在的空间
局部变量的内存在栈上开辟的,对象在堆上。 局部变量就是在方法内部定义的变量,不要和引用变量混到一起。这是两个不一样的变量
public class HelloWorld { public static void main(String[] args) { int[] array = null; System.out.println(array[0]); } }
在运行此代码时,出现空指针报错xception in thread "main" java.lang.NullPointerException,简称NPE(空指针异常)。
原因只有一个:使用了值为null的引用。
import java.util.Arrays; public class HelloWorld { public static void main(String[] args) { int[] array = {1,2,3,4}; array[0]=99; int[] array1 = array; array1[0]=100; System.out.println(Arrays.toString(array)); System.out.println(Arrays.toString(array1)); } }
两个System的输出都是[100, 2, 3, 4]
另外:
Java中没有约定null和0号地址的内存有任何关联
总结:当数组作为参数进行传递时,其实还是按值传递,不过此时的值是一个地址。 那么就会出现两种情况: 。1.形参修改指向:array new int[ ];只会影响形参的指向 2.形参修改实参所指向对象的值:array[ 0 ] =9;此时才会影响到实参
public class HelloWorld {
public static void main(String[] args) {
int[] array = {1,2,3,4};
int[] array1 = null;
String ans = myToString(array);
String ans1 = myToString(array1);
System.out.println(ans); //输出[1,2,3,4]
System.out.println(ans1); //输出null
}
public static String myToString(int[] array) {
if(array==null)return null; //如果没有,可能会出现空指针异常
String ret = "[";
for (int i = 0; i < array.length; i++) {
ret+=array[i];
if(i!= array.length-1)
ret+=",";
}
ret+="]";
return ret;
}
}
public class HelloWorld {
public static void main(String[] args) {
int[] array = {1,2,3,4};
int[] array1 = new int[array.length];
for (int i = 0; i < array.length; i++) {
array1[i] = array[i];
}
System.out.println(Arrays.toString(array));
System.out.println(Arrays.toString(array1));
}
}
public class HelloWorld {
public static void main(String[] args) {
int[] array = {1,2,3,4};
//第一个参数是被copy的数组,第二个参数是新数组的长度
int[] array1 = Arrays.copyOf(array,array.length);
System.out.println(Arrays.toString(array));
System.out.println(Arrays.toString(array1));
}
}
public static native void arraycopy(
Object src, int src srcPos, Object dest, int destPos, int length )
native表示是本地方法
public class HelloWorld { public static void main(String[] args) { int[] array = {1,2,3,4}; int[] array1 = new int[array.length*2]; //被拷贝的数组,从被拷贝的数组的哪个位置开始,拷贝到哪个数组,存放的第一个数的位置 System.arraycopy(array,0,array1,1,array.length-1); System.out.println(Arrays.toString(array)); System.out.println(Arrays.toString(array1)); } }
输出为: [1, 2, 3, 4]
[0, 1, 2, 3, 4, 0, 0, 0]注意越界问题,若越界则会出现ArrayIndexOutOfBoundsExcepyion数组越界问题
另外的另外,还有一种比较奇特的方法(克隆clone:产生一个副本)也能实现同样的效果
public class HelloWorld {
public static void main(String[] args) {
int[] array = {1,2,3,4};
int[] array1 = array.clone();
System.out.println(Arrays.toString(array));
System.out.println(Arrays.toString(array1));
}
}
另外的另外的另外的另外:拷贝分为引用拷贝、浅拷贝、深拷贝
深浅拷贝和实现的方式,和代码写的有关,和是不是for循环无关。 n具体内容可以查看引用拷贝、深浅拷贝(侵权必删)
顺序查找方便实现,但是查找的效率过于慢,故我们可以尝试一下二分查找(折半查找):
二分查找的前提是有序数组
public class a { public static int binarySearch(int[] array, int key) { int left=0; int right= array.length-1; while(left<=right) { int mid=(left+right)/2; if(key>array[mid]) left=mid+1; else if (key
1; else return mid; } return -1; } public static void main(String[] args) { int[] array = {1,2,3,4,5,6,7,8,9,10}; Arrays.sort(array);//从小到大排序 System.out.println(binarySearch(array,8));//自己写的 System.out.println(Arrays.binarySearch(array,8)); //自带的,没找到返回负数,不一定是-1 } }
关于获取时间
public static void main(String[] args) { long start = System.currentTimeMillis(); long end = System.currentTimeMillis(); System.out.println(end-start);//答案为0;差值为毫秒 }
class a {
public static void main(String[] args) {
int[][] array1 = {{1,2,3},{4,5,6}};
int[][] array2 = new int[2][3];
int[][] array3 = new int[][]{{1,2,3},{4,5,6}};
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
System.out.print(array1[i][j]);
}
System.out.println();
}//遍历
System.out.println("========");
System.out.println(Arrays.toString(array3[0]));//[1,2,3]遍历
System.out.println(Arrays.toString(array3[1]));//[4,5,6]遍历
System.out.println("==========");
for (int[] ret : array1) {
for (int x : ret) {
System.out.print(x+" ");
}
}//遍历二维数组
System.out.println("=========");
System.out.println(Arrays.deepToString(array1));//[[1,2,3],[]4,5,6]
}
}
引用不一定在栈上,在不在栈上只和是否是局部变量有关。