数组
内存是连续的 存放相同数据的集合
- 定义
- 动态初始化
new 产生一个对象
定义数组同时初始化 int
int[]arry=new int[]{1,2,3,4}
- 静态初始化
产生了对象
int[]array2={1,2,3,4};
- 定义了一个数组
没有初始化 默认值为0
int[]array3=new int[10];
- 数组访问
int[]arr={1,2,3};
System.out.println(arr[1]); 2
System.out.println(arr[0]); 1
System.out.println("length:"+arr.length); 3
System.out.println(array2);
[I@1540e19d哈希码
array.length 数组长度(数组个数) .为成员访操作符
sout(arr[0]); 输出数组中的元素角标从0开始
arr[ ] 下标访问范围[0,length-1]
地址是唯一的 哈希码也是唯一的
java.lang.ArrayIndexOutOfBoundsException: 5 at
testDemo1.main(testDemo1.java:6) 数组越界 java.lang.NullPointerException
at testDemo1.main 空指针异常
- 数组的遍历 (for for-each)
数组所有元素访问一遍 并输出
int[]arr={1,2,3};
for (int i = 0; i <arr.length ; i++) {
System.out.println(arr[i]);
}
for (int x:arr){ //for-each
System.out.println(x);
}
for循环可使用下标
foreach无法使用下标
foreach 更方便完成遍历,可避免循环条件和更新语句写错
- 数组作为方法参数
int[]arr={1,2,3};
printArray(arr);
}
public static void printArray(int[] a) {
for (int x:a){
System.out.println(x);
}
}
打印数组内容
int[ ] a 是函数形参,int[ ] arr 是函数实参
- 按值传递:
参数传内置类型
int num=0;
func1(num);
System.out.println("num="+num);
}
public static void func1(int x) {
x=10;
System.out.println("x="+x);
} x=10; num=0
形参x值不影响实参num
相当于copy一份内容给新的变量
- 引用:就是存放地址的 高配指针
参数传数组类型
int[]arr={1,2,3};
func2(arr);
System.out.println("arr[0]="+arr[0]);
}
public static void func2(int[] a) {
a[0]=10;
System.out.println("a[0]="+a[0]);
} a[0]=10; arr[0]=1;
函数内部修改参数影响外部参数值
引用传参,相当于存储地址指向参数
- 初始 JVM:
每个线程都有独立的内存区域 程序计数器、java虚拟机栈、本地方法栈。
1.程序计数器:
下一条要执行的指令。内存非常小
2.java虚拟机栈:
栈,主要用来存放局部变量表
3.本地方法栈:
主要用来调用native方法。存放native方法的局部变量表
native方法:它是由c/c++实现的方法,一般体现在源码中。
4.堆:
主要用来存放对象。new
5.方法区:
用来从放静态变量,类信息。
类信息:Class对象
6.常量池:
主要用来存放字符串常量。String str=“hello”; hello存放在常量池
JDK1.7以前,常量池存放在方法区。
JDK1.7开始,常量池挪到堆中。
- 数组作为方法返回值
//数组元素值*2
int[]arr={1,2,3};
transform(arr);
printArray(arr);
}
public static void transform(int[] arr) {
for (int i = 0; i < arr.length; i++) {
arr[i]=arr[i]*2;
}
}
public static void printArray(int [] a) {
for (int x:a){
System.out.println(x);
}
} 输出: 2 4 6
破环了原有数组,此时是引用。
int[]arr={1,2,3};
int[]output=transform(arr);
printArray(output);
}
public static int[] transform(int[] arr) {
int[]ret=new int[arr.length];
for (int i = 0; i < arr.length; i++) {
ret[i]=arr[i]*2;
}
return ret;
}
public static void printArray(int [] a) {
for (int x:a){
System.out.println(x);
}
} 输出:2 4 6
不会破坏原有数组,返回ret数组首地址给out,没有拷贝数组内容,高效
- 二维数组
本质是一堆数组,只不过每个元素又是一堆数组
基本语法 定义
int[][] arr=new int[][]{ };
数据类型[][] 数组名称 = new 数据类型[行数][列数]{初始化数据};
//定义二维数组并输出
int[][] arr = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
for (int row = 0; row < arr.length; row++) {
for (int col = 0; col < arr[row].length; col++) {
System.out.printf("%d\t",arr[row][col]);
}
System.out.println(" ");
}
}
冒泡排序
趟数 次数
public static void main(String[] args) {
int[]array={20,9,10,-1,-2,0,1,2,4,5,6};
bubbleSort(array);
}
public static void bubbleSort(int[] array) { //冒泡排序
//次数
for (int i = 0; i < array.length-1; i++) {
//趟数
int change=0; //优化
for (int j = 0; j < array.length-1-i; j++) {
if(array[j]>array[j+1]){
int tmp=array[j];
array[j]=array[j+1];
array[j+1]=tmp;
change+=1;
}
}
if (change==0){
//此趟没有更改数组元素顺序,则说明数组是有序的。
break;
}
}
System.out.println(Arrays.toString(array));
}