数组的定义与使用
1、数组定义:存放相同类型数据的集合。内存是连续的。数组可以通过下标来访问其中的元素。
数组最大的缺陷:长度固定,创建数组之后不能修改数组的大小,可以使用length属性获取数组的大小。
2、创建一维数组
// 动态初始化
int[] array = new int [ ] { 1,2,3,4,5 };
// 静态初始化
int[] array = { 1,2,3,4,5 };
int[ ] arr=new int[10] //只是定义了一个数值,默认值为0。
注意:
int [ ] arr={1,2,3};
其中数组名arr所存储的内容在栈上,是存放初始化数据的地址。
初始化的数据{1,2,3}是存储在堆上的。
创建二维数组:
int[][] array = {{1,2,3},{4,5,6}};
int[][] array2 = new int[][]{{1,2,3},{4,5,6}};
int[][] array3 = new int[2][3];
int[][] array4 = new int[2][];
int[][] array5 = {{1,2},{4,5,6}};
3、
下标访问操作不能超出有效范围 [0, length - 1] , 如果超出有效范围, 会出现下标越界异常。
eg:ArrayIndexOutOfBoundsException:
数组越界异常
还有千万要记住,数组属于引用数据类型,所以在数组使用之前一定要开辟控件(实例化),如果使用了没有开辟空间的数组,则一定会出现 NullPointerException
异常信息:NullPointerException
即:空指针异常
4、
java基本数据类型传递参数时是值传递;引用类型传递参数是引用传递。
数组引用传递
引用:就是存放地址的。引用传递的本质是:同一块堆内存空间可以被不同的栈内存所指向。
5、
数组的遍历:
1)For()循环
public static void main(String[] args) {
int[] arr={1,2,3};
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
2)foreach :
int[] arr = {1, 2, 3};
for (int x : arr) {
System.out.println(x);
}
// 执行结果 1 2 3(不能按下标单独打印)
//x :数组当中的元素 array:需要打印的数组名
3)Arrays.toString();
//将数组以字符串的形式进行打印
System.out.println(Arrays.toString(array3));
模拟Arrays.toString();方法
public static String toString(int[] array) {
String str = "[";
for (int i = 0; i < array.length; i++) {
str = str + array[i];
if(i != array.length-1) {
str += ", ";
}
}
str += "]";
return str;
}
6、JVM内存区域划分
JVM:
- 程序计数器:存放下一条指令(内存很小)
- Java虚拟机栈:平时说的栈,主要用来存放局部变量表
- 本地方法栈:主要用来调用native方法,存放native方法的局部变量。Native方法:是由C/C++代码实现的方法。一般体现在源码当中。
Public static native void arraycopy(Object src,
int srcPos,Object dest,int destPos,int length);
- 堆:主要用来存放对象的。使用 new 创建的对象都是在堆上保存 (例如前面的 new int[]{1, 2, 3} ) (堆的空间非常大,栈的空间非常小)
- 方法区:用来存放静态变量,类信息。
- 类信息:class对象。
- 常量池:主要用来存放字符串常量。String str = “hello”;就存放在常量池。在JDK1.以前,常量池放在方法区。在JDK1.7开始,他被挪到了堆里面。
7、
地址的哈希码 真实的地址哈希出来的
哈希表:地址是唯一的,哈希码也是唯一的
8、
每个线程都会有三块独立的内存区域:程序技术器,JAVA虚拟机栈,本地方法栈
9、
8种简单类型对应的0值:
Char \u0000 boolean:false
引用类型:null
运算符: . 一般来说, . 属性 , . 行为(方法)
按值传递:形参就是实参的一个拷贝。
Arrays:是java当中操作数组的工具类,将数组以字符串的形式打印
10、
Object:是所有类型的父类
Java.util.Arrays:操作数组的常用类
Java.util.:工具类
Arraycopy(Object src,int srcPos,Object dest,int destPos,int length)
其中:src:代表源数组
srcPos:从源数组的pos位置开始拷贝
dest:目的地数组
destPos:目的地数组的位置
length:拷贝的长度
copyOf(int [] 源数组,int 拷贝的长度)
注意:
Arrays.copyOf()返回值是void
System.arraycopy();返回值是int
Arrays.copyOf()底层调用的是System.arraycopy();
System.arraycopy();更快
11、
数组的拷贝:
1)、for循环去拷贝
for (int i = 0; i < array.length; i++) {
array2[i] = array[i];
}
2)、System.arraycopy
System.arraycopy(array,
0,array2,0,array.length);
3)、Arrays.copyOf
//int[] array2 = Arrays.copyOf(array,array.length);
4)、数组名.clone();
- 返回一个副本
- 数组名->你要拷贝的数组
- clone是Object的方法
int[] array2 = array.clone();
System.out.println(Arrays.toString(array2));
拷贝分为:
深拷贝:不会改变数组值
浅拷贝:
四种拷贝方式,对于数组当中如果是简单类型那么就是深拷贝;
对于与数组当中如果是引用类型那么就是浅拷贝。
以上四种类型可以对引用类型的数组进行深拷贝,但是代码的写法要进行改变
12、
学习Arrays类当中的方法:
* Arrays.toString();
* Arrays.copyOf();
* Arrays.copyOfRange();//拷贝部分数组[)
* Arrays.binarySearch();
* Arrays.equals();判断数组是否相同
* Arrays.fill(array,9); 数组的填充
* Arrays.fill(array,2,7,88);[2,7)下标填充为88
* Arrays.sort(array);将数组进行排序
Array.deepToString(array);打印全部数组。
13、程序练习
1)将数组当中奇数放到偶数前面
public static void eveAfterOdd(int[] array) {
int i = 0;
int j = array.length-1;
while (i < j) {
while (i < j && array[i] % 2 != 0) {
i++;
}//i所保存的下标就是偶数的下标
while (i < j && array[j] % 2 == 0) {
j--;
}//j所保存的下标就是奇数的下标
if(i < j) {
int tmp = array[i];
array[i] = array[j];
array[j] = tmp;
}
}
}
2)实现二分查找代码
i)
public static int binarySearch1(int[] array,int key) {
int left = 0;
int right = array.length-1;
while (left<=right) {
//int mid = (left+right)/2;
int mid = (left+right)>>>1;
if(array[mid] == key) {
return mid;
}else if(array[mid] < key) {
left = mid+1;
}else {
right = mid-1;
}
}
return -1;
}
ii)将上述程序level 一个层次
public static int binarySearch(
int[] array,int key,int left,int right) {
if(left > right) {
return -1;
}
int mid = (left+right)>>1;
if(array[mid] == key) {
return mid;
}else if(array[mid] > key) {
return binarySearch(array,key,left,mid-1);
}else {
return binarySearch(array,key,mid+1,right);
}
}
3)数组的逆置
public static void reverse(int[] array) {
int i = 0;
int j = array.length-1;
while (i < j) {
int tmp = array[i];
array[i] = array[j];
array[j] = tmp;
i++;
j--;
}
}
4)冒泡排序
class BubbleSort{
void printIntArray(int[] arr)
{
for(int x : arr){
System.out.print(x + " ");
}
System.out.println();
}
void sort(int[] arr)
{
int temp = 0;
for(int i = 1;i < arr.length;i++){
for(int j = 0;j < arr.length - i;j++){
if(arr[j] > arr[j + 1]){
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
}
将上述程序稍加改动,当程序在进行中时已再无任何交换,即可提前结束,减少运算
public static void bubbleSort(int[] array) {
boolean flg = false;
//趟数
for (int i = 0; i < array.length-1; i++) {
flg = false;//因为每一趟都有能有序
//次数
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;
flg = true;
}
}
if(!flg) {
return;
}
}
}
上一篇: 实例讲解vue v-for 数据处理