数组的概述
数组的理解:数组(Array),是多个相同类型数据按一定顺序排列的集合,并使用一个名字命名,并通过编号的方式对这些数据进行统一管理。
1.数组的声明
(String[] names//java特点、int age[]//C语言特点)
2.初始化:
①静态初始化:初始化和赋值同时进行,由程序员对数组完成赋值,然后由系统根据赋值多少来决定数组的长度。
names = new String[]{“1”,“2”};
int[] score ={1,20,100,90}(声明和初始化不能分开写)
②动态初始化:初始化和赋值分开进行,由程序员先决定数组的大小,系统来根据数组长度完成默认赋值。
age = new int[5];//5指的是数组的长度(可以放几个元素)
3.获取数组中的元素:
通过使用数组的下角标(索引值)来获取
下角标(索引值)是从0开始的到数组的长度-1
获取数组中的数据
说明
1)数组是有序排列的
2)数组属于引用数据类型的变量。数组的元素,既可以是基本数据类型,也可以是引用数据类型
3)创建数组对象会在内存中开辟一整块连续的空间
4)数组的长度一旦确定,就不能修改。
5)数组的属性:length - 数组的长度
int len = age.length;
System.out.println(len);
5.遍历数组中的所有元素
for(int i; i<name.length;i++){System.out.println(name[i]);}
6.数组元素的默认值
byte,short,int,long ->0
float,double -> 0.0
char -> \u0000
boolean ->false
引用数据类型 -> null
Arrays.toString直接赋值
String str = Arrays.toString(numbers);//Arrays是操作数组的一个工具类
System.out.println("numbers=" + str);
二维数组
理解:对于二维数组的理解,我们可以看成是一维数组array1又作为另一个一维数组array2的元素而存在。其实,从数组底层的运行机制来看,其实没有多维数组。
说明:二维数组的元素的默认值是null
1.二维数组的声明和初始化:
声明:String[][] ns、String ns2[][]、String[] ns3[]
静态初始化:
ns = new String[][]{{"xxx","15363254780"},{"xxxx","185632041025"},{"xx","19850546543"}};
声明和初始化不能分开写
String[][] persons = {{"xxx","15363254780"},{"xxxx","185632041025"},{"xx","19850546543"}};
动态初始化
ps2 = new String[3][2]; //3指的是二维数组的长度 ,2指的是二维数组元素(一维数组)的长度
ps3 = new String[3][];//声明二维数组的长度
2.给二维数的元素的元素赋值。
//获取二维数组元素的元素的值
String name = ps[2][0];//2指的二维数组的索引,0指的是一维数组的索引
System.out.println(name);
ps[2][0] = "娜扎";
3.二维数组的属性 :length
System.out.println(ps.length);//二维数组的长度
System.out.println(ps[0].length);//二维数组元素的长度
4.遍历二维数组
for (int i = 0; i < ps.length; i++) {
//获取一维数组
String[] pss = ps[i];
//遍历一维数组
for (int j = 0; j < pss.length; j++) {
System.out.print(pss[j] + " ");
}
System.out.println();
}
最终版:
for (int i = 0; i < ps.length; i++) {
for (int j = 0; j < ps[i].length; j++) {
System.out.print(ps[i][j] + " ");
}
System.out.println();
}
5.二维数组元素的默认值:null
//二维数组元素(一维数组)的元素的默认值 和 一维数组元素的默认值是一样的。
String[][] ps4 = new String[3][];
System.out.println(ps4[0]);//获取的是地址值
内存解析
堆(Heap),此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存(new出来的都在堆中(包括数组、类和接口))。这一点在Java虚拟机规范中的描述是:所有的对象实例以及数组都要在堆上分配。
通常所说的栈(Stack),是指虚拟机栈。虚拟机栈用于存储局部变量等。局部变量表存放了编译期可知长度的各种基本数据类型、对象引用(reference类型,它不等同于对象本身,是对象在堆内存的首地址)。 方法执行完,自动释放。
方法区(Method Area),用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
Arrays工具类
操作数组的工具类,里面定义了很多操作数组的方法
数组中常用涉及到的算法
1.求数值型数组中元素的最大值、最小值、平均数、总和等
int[] numbers = {10,20,6,5,3};
//求数值型数组中元素的最大值
int maxNumber = numbers[0];
for (int i = 1; i < numbers.length; i++) {
if(maxNumber < numbers[i]){
maxNumber = numbers[i];
}
}
System.out.println("最大值:" + maxNumber);
//求数值型数组中元素的最小值
int minNumber = numbers[0];
for (int i = 1; i < numbers.length; i++) {
if(minNumber > numbers[i]){
minNumber = numbers[i];
}
}
System.out.println("最小值:" + minNumber);
//求数值型数组中元素的和 ,平均数
int sum = 0;
for (int i = 0; i < numbers.length; i++) {
sum += numbers[i];
}
System.out.println("sum=" + sum + " 平均数:" + sum/numbers.length);
2.数组中Arrays工具类的使用
import java.util.Arrays;
public class ArraysTest {
public static void main(String[] args) {
//1.boolean equals(int[] a,int[] b):判断两个数组是否相等。
int[] arr1 = new int[]{1,2,3,4};
int[] arr2 = new int[]{1,3,2,4};
boolean isEquals = Arrays.equals(arr1, arr2);
System.out.println(isEquals);
//2.String toString(int[] a):输出数组信息。
System.out.println(Arrays.toString(arr1));
//3.void fill(int[] a,int val):将指定值填充到数组之中。
Arrays.fill(arr1,10);
System.out.println(Arrays.toString(arr1));
//4.void sort(int[] a):对数组进行排序。
Arrays.sort(arr2);
System.out.println(Arrays.toString(arr2));
//5.int binarySearch(int[] a,int key)
//二分法查找 - 一定要先排序,如果找不到返回负数
int[] arr3 = new int[]{-98,-34,2,34,54,66,79,105,210,333};
int index = Arrays.binarySearch(arr3, 210);
if(index >= 0){
System.out.println(index);
}else{
System.out.println("未找到");
}
}
}
3.数组的复制、反转、查找(二分查找法)
public class ArrayTest2 {
public static void main(String[] args) {
String[] arr = new String[]{"JJ","DD","MM","BB","GG","AA"};
//数组的复制(区别于数组变量的赋值:arr1 = arr)
String[] arr1 = new String[arr.length];
for(int i = 0;i < arr1.length;i++){
arr1[i] = arr[i];
}
//数组的反转
//方法一:
// for(int i = 0;i < arr.length / 2;i++){
// String temp = arr[i];
// arr[i] = arr[arr.length - i -1];
// arr[arr.length - i -1] = temp;
// }
//方法二:
// for(int i = 0,j = arr.length - 1;i < j;i++,j--){
// String temp = arr[i];
// arr[i] = arr[j];
// arr[j] = temp;
// }
//遍历
for(int i = 0;i < arr.length;i++){
System.out.print(arr[i] + "\t");
}
System.out.println();
//查找(或搜索)
//线性查找:
String dest = "BB";
dest = "CC";
boolean isFlag = true;
for(int i = 0;i < arr.length;i++){
if(dest.equals(arr[i])){
System.out.println("找到了指定的元素,位置为:" + i);
isFlag = false;
break;
}
}
if(isFlag){
System.out.println("很遗憾,没有找到的啦!");
}
//二分法查找:要求此数组必须是有序的。
int[] arr3 = new int[]{-99,-54,-2,0,2,33,43,256,999};
boolean isFlag = true;
int number = 256;
//int number = 25;
int head = 0;//首索引位置
int end = arr3.length - 1;//尾索引位置
while(head <= end){
int middle = (head + end) / 2;
if(arr3[middle] == number){
System.out.println("找到指定的元素,索引为:" + middle);
isFlag = false;
break;
}else if(arr3[middle] > number){
end = middle - 1;
}else{//arr3[middle] < number
head = middle + 1;
}
}
if(isFlag){
System.out.println("未找打指定的元素");
}
4.数组元素的排序算法——冒泡排序
int[] numbers = {10,20,6,5,3};
//控制几轮 {0,1,2,3,4}
for (int i = 0; i < numbers.length - 1; i++) {
//控制每轮比较的次数 {第一轮的j的值 :0,1,2,3 }
for (int j = 0; j < numbers.length - 1 - i; j++) {
//判断是否需要交换
if(numbers[j] > numbers[j + 1]){
//数据交换
int temp = numbers[j];
numbers[j] = numbers[j + 1];
numbers[j + 1] = temp;
}
}
}
数组中常见的异常
数组中常见的异常:
1.下角标越界:ArrayIndexOutOfBoundsException
原因 :因为使用的索引值没有在合理范围(0~数组的长度-1)之内
2.空指针异常:NullPointerException
原因 :只要调用属性和方法的那个值为null就会发生空指针异常
//1.下角标越界:ArrayIndexOutOfBoundsException
int[] numbers = new int[2]; //0 ~ 1是可以的
//System.out.println(numbers[2]); 编译错误:超出了索引值的范围
//System.out.println(numbers[-1]);编译错误:超出了索引值的范围
//2.空指针异常:NullPointerException
String str = "aaa";
str = null;
// System.out.println(str.toUpperCase());编译错误: 因为str的内容为null
String[][] ps = new String[2][3];
// System.out.println(ps[0][0].toUpperCase());编译错误: 因为ps[0][0]的内容为null
String[][] ps2 = new String[2][];//二维数组的元素的默认值为null
System.out.println(ps2[0][0]);//编译错误:因为ps2[0]为null