数组
数组指的就是一组相关变量的集合。例如:如果说现在要想定义100个整型变量,按照传统的思路,可能这样定义:
int i1,i2 ,... i100,一共写100个变量。
以上的形式的确可以满足技术要求,但是这里有一个问题,这100多个变量没有任何的逻辑的控制关系,完全独立,就会出现对象不方便管理的情况。那么在这种情况下就可以利用数组来解决此类问题。
数组的定义语法
- 声明并开辟数组:
数据类型 数组名称 [] = new 数据类型 [长度] ;
数据类型 [] 数组名称 = new 数据类型 [长度] ;
- 分步完成:
声明数组:数据类型 数组名称 [] = null ;
开辟数组:数组名称 = new 数据类型 [长度] ;
数组操作说明
当数组开辟空间之后,那么可以采用“数组名称[下标|索引]”的形式进行访问,但是所有数组的下标都是从0开始的,即:如果是3个长度的数组,那么下标的范围:0 ~ 2(0、1、2一共是三个内容)。如果访问的时候超过了数组的允许下标的长度,那么会出现数组越界异常(ArrayIndexOutOfBoundsException)。
以上给出的数组定义结构使用的是动态初始化的方式,即:数组会首先开辟内存空间,但是数组中的内容都是其对应数据类型的默认值,如果现在声明的是int型数组,则数组里面的全部内容都是其默认值:0。
由于数组是一种顺序的结构,并且数组的长度都是固定的,那么可以使用循环的方式输出,很明显需要知道for循环,而且在Java里面为了方便数组的输出提供有一个“数组名称.length”的属性,可以取得数组长度。
定义数组
public class ArrayDemo {
public static void main(String args[]) {
int data[] = new int[3]; // 声明并开辟了一个3个长度的数组
data[0] = 10; // 设置数组内容
data[1] = 20; // 设置数组内容
data[2] = 30; // 设置数组内容
for (int x = 0; x < data.length; x++) { // 循环输出数组
System.out.print(data[x] + "、");
}
}
}
程序执行结果: 10、20、30、
数组操作
数组的引用传递
public class ArrayDemo {
public static void main(String args[]) {
int data[] = new int[3]; // 声明并开辟了一个3个长度的数组
data[0] = 10; // 设置数组内容
data[1] = 20; // 设置数组内容
data[2] = 30; // 设置数组内容
int temp[] = data; // 数组引用传递
temp[0] = 99; // 修改数组内容
for (int x = 0; x < data.length; x++) { // 循环输出数组
System.out.print(data[x] + "、");
}
}
}
程序执行结果: 99、20、30、
数组引用传递
数组静态初始化
- 格式一:简化格式
数据类型 数组名称 [] = {值,值,...} ;
- 格式二:完整格式
数据类型 数组名称 [] = new 数据类型 [] {值,值,...} ;
public class ArrayDemo {
public static void main(String args[]) {
int data[] = new int[] { 1, 2, 3, 4, 5 }; // 数组的静态初始化
for (int x = 0; x < data.length; x++) { // 循环输出数组
System.out.print(data[x] + "、");
}
}
}
程序执行结果: 1、2、3、4、5、
二维数组
二维数组的定义语法
- 动态初始化:
数据类型 数组名称[][] = new 数据类型[行的个数][列的个数];
- 静态初始化:
数据类型 数组名称[][] = new 数据类型[][] {{值,值,值},{值,值,值}}
观察二维数组的定义及使用
public class ArrayDemo {
public static void main(String args[]) {
int data [][] = new int [][] {
{1,2,3} ,{4,5,6} , {7,8,9}
} ; // 定义二维数组
for (int x = 0; x < data.length; x++) {// 外层循环是控制数组的数据行内容
for (int y = 0; y < data[x].length; y++) { // 内层循环是控制数组的数据列内容
System.out.print(data[x][y] + " ");
}
System.out.println(); // 换行
}
}
}
程序执行结果:
1 2 3
4 5 6
7 8 9
数组与方法参数的传递
既然数组内容可以进行引用传递,那么就可以把数组给方法之中的参数,而如果一个方法要想接收参数,则对应的参数类型必须是数组。
一个数组传递的程序
public class ArrayDemo {
public static void main(String args[]) {
int data[] = new int[] { 1, 2, 3 }; // 开辟数组
change(data); // 引用传递,等价于:int temp [] = data ;
for (int x = 0; x < data.length; x++) {
System.out.print(data[x] + "、");
}
}
/**
* 此方法的主要功能是进行数组数据的改变操作,在本方法中会将数组中的每个元素内容乘2
* @param temp 要进行改变内容的数组引用
*/
public static void change(int temp[]) { // 此方法定义在主类中,并且由主方法直接调用
for (int x = 0; x < temp.length; x++) {
temp[x] *= 2; // 将数组的内容乘2保存
}
}
}
程序执行结果: 2、4、6、
数组与方法间的引用传递
数组排序
public class ArrayDemo {
public static void main(String args[]) {
int data [] = new int [] {2,1,9,0,5,3,7,6,8} ;
sort(data) ; // 实现排序
print(data) ;
}
public static void sort(int arr[]) { // 这个方法专门负责排序
for (int x = 0 ; x < arr.length ; x ++) {// 外层控制排序总体的次数
for (int y = 0 ; y < arr.length - 1 ; y ++) { // 内层控制每次的排序控制
if (arr[y] > arr[y + 1]) { // 判断需要交换
int t = arr[y] ;
arr[y] = arr[y + 1] ;
arr[y + 1] = t ;
}
}
}
}
public static void print(int temp[]) {// 专门定义一个输出的功能的方法
for (int x = 0 ; x < temp.length ; x ++) {
System.out.print(temp[x] + "、") ;
}
System.out.println() ;
}
}
实现数组的转置(首尾交换) —— 实现思路(元素长度为偶数)
实现数组的转置(首尾交换) —— 实现思路(元素长度为奇数)
public class ArrayDemo {
public static void main(String args[]) {
int data [] = new int [] {1,2,3,4,5,6,7} ;
reverse(data) ;// 实现转置
print(data) ; // 输出数组内容
}
public static void reverse(int arr[]) { // 此方法专门实现数组的转置操作
int len = arr.length / 2 ;// 转置的次数
int head = 0 ; // 头部索引
int tail = arr.length - 1 ; // 尾部索引
for (int x = 0 ; x < len ; x ++) { // 循环次数为数组长度÷2
int temp = arr[head] ;// 数据交换
arr[head] = arr[tail] ;// 数据交换
arr[tail] = temp ;// 数据交换
head ++ ;// 头部索引增加
tail -- ;// 尾部索引减少
}
}
public static void print(int temp[]) { // 数组输出
for (int x = 0 ; x < temp.length ; x ++) {
System.out.print(temp[x] + "、") ;
}
System.out.println() ;
}
}
程序结果:
7、6、5、4、3、2、1、
数组操作方法
数组拷贝:可以将一个数组的部分内容拷贝到另外一个数组之中;
System.arraycopy(源数组名称,源数组拷贝开始索引,目标数组名称,目标数组拷贝开始索引,长度)
数组排序:可以按照由小到大的顺序对基本数据类型的数组(例如:int数组、double数组都为基本类型数组)进行排序。
java.util.Arrays.sort(数组名称);
实现数组拷贝
public class ArrayDemo {
public static void main(String args[]) {
int dataA[] = new int[] { 1, 2, 3, 4, 5, 6, 7, 8 }; // 定义数组
int dataB[] = new int[] { 11, 22, 33, 44, 55, 66, 77, 88 };// 定义数组
System.arraycopy(dataA, 4, dataB, 2, 3); // 数组拷贝
print(dataB);
}
public static void print(int temp[]) { // 打印数组内容
for (int x = 0; x < temp.length; x++) {
System.out.print(temp[x] + "、");
}
System.out.println();
}
}
程序执行结果: 11、22、5、6、7、66、77、88、
实现排序
public class ArrayDemo {
public static void main(String args[]) {
int data[] = new int[] { 3, 6, 1, 2, 8, 0 };
java.util.Arrays.sort(data); // 数组排序
print(data);
}
public static void print(int temp[]) {// 数组输出
for (int x = 0; x < temp.length; x++) {
System.out.print(temp[x] + "、");
}
System.out.println();
}
}
程序执行结果: 0、1、2、3、6、8、
对象数组
数组是引用类型,而类也同样是引用类型,所以如果是对象数组的话表示一个引用类型里面嵌套其它的引用类型。
在之前使用的数组都属于基本数据类型的数组,但是所有的引用数据类型也同样可以定义数组,这样的数组称为对象数组。如果要想定义对象数组(以类为例),可以采用如下的形式完成:
- 对象数组的动态初始化:
类名称 对象数组名称 = new 类名称 [长度] ;
- 对象数组的静态初始化:
类名称 对象数组名称 = new 类名称 [] {实例化对象,实例化对象,...} ;
对象数组的动态初始化
class Book {
private String title ;
private double price ;
public Book(String t,double p) {
title = t ;
price = p ;
}
// setter、getter、无参构造略
public String getInfo() {
return "书名:" + title + ",价格:" + price ;
}
}
public class ArrayDemo {
public static void main(String args[]) {
Book books [] = new Book[3] ; // 开辟了一个3个长度的对象数组,内容为null
books[0] = new Book("Java",79.8) ; // 对象数组中的每个数据都需要分别实例化
books[1] = new Book("JSP",69.8) ; // 对象数组中的每个数据都需要分别实例化
books[2] = new Book("Android",89.8) ; // 对象数组中的每个数据都需要分别实例化
for (int x = 0 ; x < books.length ; x ++) { // 循环对象数组
System.out.println(books[x].getInfo()) ;
}
}
}
程序执行结果:
书名:Java,价格:79.8
书名:JSP,价格:69.8
书名:Android,价格:89.8
对象数组的静态初始化
public class ArrayDemo {
public static void main(String args[]) {
Book books[] = new Book[] {
new Book("Java", 79.8),
new Book("JSP", 69.8),
new Book("Android", 89.8) }; // 开辟了一个三个长度的对象数组
for (int x = 0; x < books.length; x++) { // 循环输出对象数组内容
System.out.println(books[x].getInfo());
}
}
}
程序执行结果:
书名:Java,价格:79.8
书名:JSP,价格:69.8
书名:Android,价格:89.8
对象数组内存关系
对象数组的最大好处是将多个对象统一进行了管理,并且除了数据类型改变之外,和之前的数组也没有任何的区别,而且数组本身就属于引用数据类型,那么对象数组就是在一个引用数据类型之中嵌入了其他的引用数据类型,如果非要用内存图表示的话,可以简单理解为图所示的结构。