1.数组基本概念
数组:一组相关类型的变量集合,并且这些变量可以按照统一的方式进行操作
数组属于引用数据类型,有内存分配问题。
(1)数组的动态初始化(即声明并开辟空间)
① 语法如下:
数据类型[] 数组名称 = new 数组类型[长度];
特点:先开辟空间,而后再使用的时候在使用索引进行内容的设置。
② 数组的访问(通过索引完成)
语法:
数组名称[索引下标];
注意:数组 的索引是从0开始的,因此采用的索引范围就是0~(数组长度-1);
eg:int arr = new int[3]; //创建一个元素个数为3的整型数组,那么该数组的索引下标可以为:0、1、2
如果超过索引下标范围访问数组,就会产生数组越界异常,系统会报异常信息“java.lang.ArrayindexOutOfBoundsExecption”。
③ 当数组动态初始化开辟空间后,数组之中的每个元素都是该类型元素的默认值。
④ 数组本身是一个有序的集合操作,所以对于数组的内容操作往往采取循环模式完成。(数组是一个有限的集合,采用for循环)。
⑤ 在Java中有一种动态取得数组长度的方法:数组名称.length;
示例:
public class Test{
public static void main(String[] args){
//动态开辟空间
int[] arr = new int[3];
//获取数组长度
System.out..println("数组元素个数:"+arr.length);
//通过索引初始化
arr[0] = 10;
arr[1] = 20;
arr[2] = 30;
//使用for循环对数组内容进行输出
for(int i = 0; i < arr.length; i++){
System.out.print(arr[i]+"\t");
}
}
}
⑥ 分步数组空间开辟及初始化
语法示例:
int[] x = null;
x = new int[3];
注意:数组属于引用数据类型,因此在使用之前一定要开辟空间(实例化),否则会产生空指针错误NullPointerExecption。
(2)数组的引用传递
① 数组开辟空间时的内存状态
程序示例:
public class Test{
public static voud main(String[] args){
//数组的声明
int[] arr = null;
//开辟空间
arr = new int[3];
//赋值
arr[0] = 10;
arr[1] = 20;
arr[2] = 30;
//输出
for(int i = 0; i < arr.lrngth; i++){
System.out.print(arr[i] + "\t");//通过循环控制下标索引的修改
}
}
}
在内存中的表示图解如下:
注意:一块栈内存只能保存一块堆内存的内存地址;
同一块堆内存空间可以被不同栈内存指向。
示例:一块堆内存被不同栈内存指向
public class Test{
public static void main(String[] args){
int[] arr = null;
int[] tmp = null;
//给arr开辟空间
arr = new int[3];
//arr赋值
arr[0] = 10;
arr[1] = 20;
arr[2] = 30;
//让tmp指向arr所指向的堆内存,并对指向内容进行修改
tmp = arr;
tmp[0] = 50;
Sytsem.out.println(arr[0]);
}
}
图解如下:
(3)数组的竞态初始化
语法格式:
① 数据类型[] 数组名称 = {值1,值2,...} //简化格式
示例:
public class Test{
public static void main(String[] args){
int[] arr = {12,34,12,45,55,90};
System.out.println(arr.length);
for(int i = 0; i < arr.length; i++){
System.out.print(arr[i] + "\t");
}
}
}
② 数据类型[] 数组名称 = new 数据类型[]{值1,值2,...} //完整格式(推荐使用)
使用完整格式还可以用来初始化匿名数组。
示例:
public class Test{
public static void main(String[] args){
System.out.println(new int[]{1,2,3,4,5,6,7}.length);
}
}
数组的最大缺陷:长度固定(存在越界问题)
2.二维数组
(1)概念
一维数组:通过一个索引就可以取得唯一的一个记录,这样的数组称为一维数组。
二维数组:本质上指的是一个行列的集合。数组的数组就是二维数组。
在二维数组中如果要获得一个数据,既需要行索引,也需要列索引。
(2)二维数组的表示
在这种结构中,弱国要确定一个数据,则需要使用“数组名称[行索引][列索引]”来表示。这样的结构其实就是一个表的结构。
(3)二维数组的定义
① 动态初始化
数据类型[][] 对象数组 = new 数据类型[行个数][列个数];
② 静态初始化
数据类型[][] 对象数组 = new 数据类型[][]{{值,值,...},{值,值,...},...};
示例:定义一个二维数组
public class Test{
public static void main(String[] args){
int[] arr = {
{1,2,3},
{5,6,7,8},
{11,12,13,14,15}
};
for(int i = 0; i < arr.length; i++){
for(int j = 0; j < arr[i].length; j++){
System.out.print("a["+i+"]["+j+"] = "+a[i][j]+"\t");
}
System.out.println();
}
}
}
运行结果:
3.数组与方法互操作
因为数组时引用数据类型,所有引用数据类型都可以为其设置多个栈内存指向。所以在进行数组操作的时候,也可以将其通过方法进行处理。
① 使用方法接收数组
示例:
public class Test{
public static void main(String[] args){
int[] arr = new int[]{1,2,3,4,5,6,7};
printArray(arr);//等价于:int[] tmp = arr;
}
public static void printArray(int[] a){
for (int i = 0;i < a.length;i++){
System.out.print(a[i]+"\t");
}
}
}
② 使用方法返回数组
示例:
public class Test{
public static void main(String[] args){
int[] arr = init();
printArray(arr);
}
//返回数组
public static int[] init(){
return new int[]{1,2,3,4,5,6,7};
}
public static void printArray(int[] a){
for (int i = 0;i < a.length;i++){
System.out.print(a[i]+"\t");
}
}
}
③ 使用方法修改数组
示例:
public class Test{
public static void main(String[] args){
int[] arr = init();
printArray(arr);
}
//使用方法返回数组
public static int[] init(){
return new int[]{1,2,3,4,5,6,7};//匿名数组
}
//使用方法修改数组
public static void bigger(int[] a){
for(int i = 0;i
4.Java对数组的支持
(1)数组排序:java.util.Arrays.sort(数组名称);
示例:实现数组排序操作
public class Test{
public static void main(String[] args){
int[] a = new int[]{12,1,12,4,42,5,8,6,7};
char[] b = new char[]{'c','d','a','q','h','s'};
java.util.Arrays.sort(a);
java.util.Arrays.sort(b);
printArray(a);
printArray(b);
}
public static void printArray(int[] a){
for (int i = 0;i < a.length;i++){
System.out.print(a[i]+"\t");
}
System.out.println();
}
//方法重载
public static void printArray(char[] a){
for (int i = 0;i < a.length;i++){
System.out.print(a[i]+"\t");
}
System.out.println();
}
}
运行结果如下:
注意:只要是基本数据类型的数组,sort方法都可以进行排序处理(升序)。
sort排序内部使用的是双轴快速排序。
(2)数组拷贝:指的是将一个数组的部分内容替换成另一个数组的部分内容(必须是连续的内容)
语法:
System.arraycopy(源数组名称,源数组开始点,目标数组名称,目标数组开始点,拷贝长度);
示例:实现数组的拷贝
目标数组A:1、2、3、4、5、6、7
源数组B:11、22、33、44、55、66、77
替换后:1、55、66、77、5、6、7
public class Test{
public static void main(String[] args){
int[] A = new int[]{1,2,3,4,5,6,7};
int[] B = new int[]{11,22,33,44,55,66,77};
System.arraycopy(B,4,A,1,3);
printArray(A);
}
public static void printArray(int[] a){
for (int i = 0;i < a.length;i++){
System.out.print(a[i]+"\t");
}
System.out.println();
}
}
运行结果:
5.数组案例
(1)数组数据统计
要求:给一个数组,要求可以统计出该数组的最大值、最小值、平均值和总和。
eg:
目标数组:14,3,4,55,77,6,9,8
代码实现:
public class Test {
public static void main(String[] args) {
processData(new int[]{14,3,4,55,77,6,9,8});
}
public static void processData(int[] a){
int max = a[0];
int min = a[0];
int sum = a[0];
for(int i = 1;i < a.length; i++){
sum = sum + a[i];
if(a[i] > max){
max = a[i];
}
if(a[i] < min){
min = a[i];
}
}
System.out.println("最大值:"+max);
System.out.println("最小值:"+min);
System.out.println("平均值:"+(double)sum/a.length);
System.out.println("总和:"+sum);
}
}
运行结果如下:
6.对象数组
(1)对象数组的动态初始化
语法:
类名称[] 对象数组名称 = new 类名称[长度];
示例:
class Person{
String name;
int age;
public Person(String name,int age){
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "{name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class Test {
public static void main(String[] args) {
//动态初始化
Person[] s = new Person[3];
s[0] = new Person("张三",18);
s[1] = new Person("李四",20);
s[2] = new Person("王五",21);
for(int i = 0;i
(2)对象数组的静态初始化
示例:
class Person{
String name;
int age;
public Person(String name,int age){
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "{name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class Test {
public static void main(String[] args) {
//静态初始化
Person[] s = new Person[]{
new Person("张三",18),
new Person("李四",20),
new Person("王五",21)
};
for(int i = 0;i