数组

数组

(1)、是一种引用数据类型,不属于基本数据类型。父类是Object。

(2)、是一个容器。可以容纳多个元素(数组是一个数据的集合)

(3)、数组当中可以存储“基本数据类型”的数据也可以存储“引用数据类型” 的数据
例:

package javaCoreTest;

//数组中存储引用数据类型

public class ArrayTest06 {

	public static void main(String [] args) {
		Animal a1 = new Animal();
		Animal a2 = new Animal();
		Animal [] animal = {a1, a2};
		
		//对animal数组进行遍历
		for(int i = 0; i < animal.length; i++) {
			animal[i].move();
		}
		
		Animal [] aa = {new Cat(), new Bird()};
		for(int i = 0; i < aa.length; i++) {
			//这个取出的可能是Cat,也可能是Bird,不过肯定是一个Animal
			//如果调用的方法是父类中存在的方法不需要向下转型。直接使用父类型引用调用即可
			aa[i].move();
			
			//如果调用子类特有的方法需要向下转型
			if(aa[i] instanceof Cat) {
				Cat cat = (Cat)aa[i];
				cat.catMouse();
			}else if(aa[i] instanceof Bird) {
				Bird bird = (Bird)aa[i];
				bird.birdSinging();
			}
			
		}
	}
}

class Animal{
	public void move() {
		System.out.println("Animal move....");
	}
}

class Cat extends Animal{
	public void move() {
		System.out.println("猫在走猫步");
	}
	
	public void catMouse() {
		System.out.println("猫吃老鼠");
	}
}

class Bird extends Animal{
	public void move() {
		System.out.println("Bird fly!");
	}
	
	public void birdSinging() {
		System.out.println("Bird is singing.");
	}
}

运行结果:

Animal move....
Animal move....
猫在走猫步
猫吃老鼠
Bird fly!
Bird is singing.

(4)、数组对象存储在堆内存当中。

(5)、数组当中如果存储的是“Java对象”的话,实际上存储的是对象的“引用(内存地址)”,数组是不能直接存储Java对象的。

(6)、数组一旦创建,在Java中规定,长度不可变。

(7)、所有的数组都有length属性(Java自带的),用来获取数组中元素的个数

(8)、Java中的数组要求数组中元素类型统一。比如int类型数组只能存储int类型,Person类型数组只能存储Person类型。

(9)、数组元素内存地址连续。

(10)、数组中首元素的内存地址作为整个数组对象的地址

(11)、数组中的每个元素都有下标,下标从零开始,以1递增,最后一个元素的下标是:length-1
例:

package javaCoreTest;

public class ArrayTest01 {

	public static void main(String [] args) {
		//使用静态初始化的方法声明一个数组
		int [] a = {1, 2, 78, 99, 100}; 
		
		//所有数组都有length属性
		System.out.println("数组中的元素个数:" + a.length);//数组中的元素个数:5
		
		//通过下标对数组中的元素进行取
		System.out.println("第一个元素:" + a[0]);//第一个元素:1
		System.out.println("最后一个元素:" + a[a.length - 1]);//最后一个元素:100
		
		//通过下标对数组中的元素进行存(改)
		a[0] = 111;
		a[a.length - 1] = 0;
		
		System.out.println("第一个元素:" + a[0]);//第一个元素:111
		System.out.println("最后一个元素:" + a[a.length - 1]);//最后一个元素:0
		
		//数组正序遍历
		for(int i = 0; i<a.length; i++) {
			System.out.print(" " + a[i]);// 111 2 78 99 0
		}
		
		System.out.println();
		
		//数组逆序遍历
		for(int i = a.length - 1; i >= 0; i--) {
			System.out.print(" " + a[i]);//0 99 78 2 111
		}
	}
}

(12)、数组这种数据结构的优点和缺点是什么?

**优点: 查询/查找/检索某个下标上的元素时效率极高,可以说是效率最高的一个数据结构。 为什么效率高?【面试时会问】 -每一个元素的内存地址在空间存储上是连续的 -每一个元素类型相同,所以占用空间大小一样
-知道第一个元素内存地址,知道每个元素占用空间的大小,又知道下标,所以通过一个数学表达式就可以计算出某个下标上元素的内存地址。直接通过内存地址定位元素,所以数组的检索效率是最高的。

注:数组中存储100个元素和存储100万个元素,在元素的查找方面效率是相同的,因为数组中元素查找的时候不会一个一个找,是通过数学表达式计算出来的。

**缺点:
-由于为了保证数组中每个元素的内存地址连续,所以在数组上随机删除或者增加元素的时候,效率较低,因为随机增删元素会涉及到后面元素统一想想或向后位移的操作。

注意:对于数组最后一个元素的增删是没有效率影响的。

-数组不能存储大数据量。 为什么?
因为很难在内存空间上找到一块特别大的连续内存空间

(12)、怎么声明/定义一个一维数组?

  • 语法格式:

     		int  [] array1;
     		doouble [] array2;
     		String [] array3;
     		boolean [] array4;
    

(13)、怎么初始化一个一维数组?

  • 包括两种方法:

     		-静态初始化
     			语法格式:int [] array = {100, 2100, 01, 03};
     		-动态初始化
     			语法格式:int [] array = new int[5];
     			//这里的5表示数组的元素个数,
     			//初始化一个5个长度的int类型数组,每个元素默认值为0
     			  String [] array = new String[6];
     			//初始化6个长度的String类型数组,每个元素默认值null
     			例:
    
package javaCoreTest;
//动态初始化数组
public class ArrayTest02 {

	public static void main(String [] args) {
		//声明/定义一个数组,采用动态初始化的方式创建
		int [] a = new int [4];
		
		//遍历数组
		for(int i = 0; i < a.length; i++) {
			System.out.println("数组中下标为" + i + "的元素为:" + a[i]);
		}
		
		//初始化一个Object类型的数组,采用动态初始化的方式
		Object [] obj = new Object[3];//每个元素默认值是null
		
		for(int i = 0; i < obj.length; i++) {
			System.out.println(obj[i]);
		}
	}
}
package javaCoreTest;

//当一个方法的参数是一个数组的时候,可以采用这种方法

public class ArrayTest03 {

	public static void main(String [] args) {
		//采用静态初始化一维数组
		int [] x = {1, 2, 3, 4};
		printArray(x);//1234
		
		System.out.println("------------------------------------");
		
		//如果直接传递一个静态数组,语法必须这样写
		printArray(new int [] {1, 2, 3});//123
		
		System.out.println("------------------------------------");
		
		//采用动态初始化一维数组
		int [] a = new int [4];
		printArray(a);//0000
		
		System.out.println("=========================");
		printArray(new int [3]);//000
	}
	
	public static void printArray(int [] array) {
		for(int i = 0; i < array.length; i++) {
			System.out.println(array[i]);
		}
	}
	}

(14)、什么时候才要静态初始化方式?什么时候采用动态初始化方式?

  • -当创建数组的时候, 确定数组中存储具体的元素时,采用静态初始化方式。

  • -当创建数组的时候,不确定数组中存储哪些数据,可以采用动态初始化的方式,预先分配内存空间。

(15)、关于一维数组的扩容
先新建一个大容量的数组,然后将小容量的数组中的数据一个一个地拷贝到大数组中。
例:

	package javaCoreTest;

//数组拷贝

public class ArrayTest07 {

	public static void main(String [] args) {
		//System.arraycopy(5个参数)
		
		//拷贝源(从这个数组中拷贝)
		int [] src = {1, 11, 22, 3, 4};
		
		//拷贝目标(拷贝到这个目标数组上)
		int [] dest = new int [20];
		
		//调用JDK System类中的arraycopy方法
		System.arraycopy(src, 1, dest,3, 2);
		
		//遍历
		for(int i = 0; i < dest.length; i++) {
			System.out.print(" " + dest[i]);
			// 0 0 0 11 22 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
		}
		
		System.out.println();
		
		//数组中存储字符串引用时
		String [] strs = {"hello", "world", "java", "oracle", "mysql", "jdbc"};
		String [] newStrs = new String[20];
		
		System.arraycopy(strs, 0, newStrs, 0, strs.length);
		for(int i = 0; i < newStrs.length; i++) {
			System.out.print(" " + newStrs[i]);
			 //hello world java oracle mysql jdbc null null null null null null null null null null null null null null
		}
	}
}

结论:数组扩容效率较低,因为涉及到拷贝的问题。在以后的开发中注意:尽可能地减少数组拷贝。

(16)、二维数组

  • -二维数组其实是一个特殊的一维数组,特殊在这个二维数组当中的每一个元素是一个一维数组。

  • -二维数组静态初始化:

    int[][]array = {{1, 2, 3}, {2, 3, 4, 5}, {0, 0}};
    注意大括号后面的引号

			package javaCoreTest;

public class ArrayTest08 {

	public static void main(String [] args) {
		//一维数组
		int [] array = {100, 200, 300};
		
		//二维数组
		int [][] a = {
				{100, 200, 300},
				{30, 20, 40, 50, 60},
				{6, 7, 9, 1},
				{0}
		};
		
		System.out.println(a.length);//4
		System.out.println(a[0].length);//3
		System.out.println(a[1].length);//5
		System.out.println(a[2].length);//4
		System.out.println(a[3].length);//1
	}
}

(17)、关于二维数组中元素的读和取
a[二维数组中一维数组的下标][一维数组的下标]
例:a[0][0]:表示一个一维数组中的第一个元素

package javaCoreTest;

//关于二维数组中元素的读和改

public class ArrayTest09 {

	public static void main(String [] args) {
		int [][] a = {
				{34, 4, 65},
				{100, 200, 300, 111},
				{0}
		};
		
		//取出二维数组中的第一个一维数组
		int [] a0 = a[0];
		//第一个一维数组中的第一个元素
		int a00 = a0[0];
		System.out.println(a00);//34
		
		//合并以上代码
		System.out.println(a[0][0]);//34
		
		//改
		a[2][0] = 1111;
		System.out.println(a[2][0]);//1111
	}
}

遍历:

package javaCoreTest;

//遍历二维数组

public class ArrayTest10 {

	public static void main(String [] args) {
		//静态初始化二维数组
		String [][] array = {
				{"java", "oracle", "c++", "C#"},
				{"zhangsan", "lisi", "wangtiechui"},
				{"lucy", "jack", "rose"}
		};
		
		//遍历二维数组
		for(int i = 0; i < array.length; i++) {
			for(int j = 0; j < array[i].length; j++) {
				System.out.print(array[i][j] + " ");
			}
			System.out.println();
		}
		
		//动态初始化二维数组
		int [][] a = new int[3][4];
		
		for(int i = 0; i < a.length; i++) {
			for(int j = 0; j < a[i].length; j++) {
				System.out.print(a[i][j] + " ");
			}
			System.out.println();
		}
	}
}

运行结果:

java oracle c++ C# 
zhangsan lisi wangtiechui 
lucy jack rose 
0 0 0 0 
0 0 0 0 
0 0 0 0 

(18)、数组常见的算法

  • 排序算法:

     			冒泡排序
     			选择排序
    
  • 查找算法:

     			二分法查找
    

    算法实际上在Java中不需要精通,因为Java中已经封装好了,要排序调用方法就行,

    例如:
    Java中提供了一个数组工具类:java.util.Arrays
    Arrays是一个工具类。
    其中有一个sort()方法,可以排序,静态方法,直接使用类名调用就行。
    例:

package javaCoreTest;

import java.util.Arrays;

/**
 * 使用以下SUN公司提供的数组工具类:java.util.Arrays;
 * @author SKX
 *
 */

public class ArraysTest01 {

	public static void main(String [] args) {
		int [] arr = {1, 55, 78, 2, 99, 0, 100};
		
		Arrays.sort(arr);
		
		for(int i = 0; i < arr.length; i++) {
			System.out.print(arr[i] + " ");
		}
	}
}

	

(19)、
/*

  • main方法上面的“String [] args"有什么用?
    • 分析以下:谁负责调用main方法(JVM)
  • JVM调用main方法的时候,会自动传一个String数组过来
    */
package javaCoreTest;

public class ArrayTest04 {

	public static void main(String [] args) {
		//JVM默认传递过来的这个数组对象的长度?默认0
		//通过测试:args不是null
		System.out.println("JVM传递过来的String数组参数,他这个数组的长度是?" + args.length);
		
		//以下这一行代码表示的含义:数组对象创建了,但是数组中没有任何数据。
		//String [] strs = new String[0];
		//String [] strs = {};
		//printLength(strs);
		
		//这个数组什么时候会有值呢?
		//其实这个数组是留给用户的,用户可以在控制台上输入参数,这个参数自动会被转换为“String[] args"
		//例如:这样的运行程序:java ArrayTest04 abc def xyz
		//那么这个时候JVM会自动将abc def xyz通过空格的方式进行分离,分离完成之后,自动放至String [] args数组当中。
		//把abc def xyz转换成字符串数组:{"abc", "def", "xyz"}
		
		//如何输入元素运行:
		//Run-->run Configurations-->arguments-->在program arguments中输入元素
		for(int i = 0; i < args.length; i++) {
			System.out.println(args[i]);
		}
	}
	
	public static void printLength(String [] args) {
		System.out.println(args.length);//0
	}
}

例: * 模拟一个系统,假设这个系统要使用,必须输入用户名和密码


package javaCoreTest;

/*
 * 模拟一个系统,假设这个系统要使用,必须输入用户名和密码
 */
public class ArrayTest05 {
	//用户名和密码输入到String [] args数组当中
	public static void main(String [] args) {
		if(args.length != 2) {
			System.out.println("使用该系统时请输入程序参数,参数中包括用户名和密码信息, 例如:zhangsan 123");
			return;
		}
		
		//程序执行到此处说明用户确实提供了用户名和密码
		//接下来你应该判断用户名和密码是否正确
		//首先取出用户名和密码
		String username = args[0];
		String password = args[1];
		
		//假设用户名是admin,密码是123时表示登录成功
		//判断两个字符串是否相等,需要使用equals方法
		//if(username.equals("admin") && password.equals("123")) {
		//以下的语句可以避免空指针异常(编程经验)
		if("admin".equals(username) && "123".equals(password)) {
			System.out.println("登录成功");
		}
		else {
			System.out.println("用户名或密码不正确");
		}
	}
}

*表示栈的压栈、弹栈动作,用一维数组

package javaCoreTest;

public class ArrayTest11 {
	
	public static void main(String [] args) {
		ArrayTest11 arr = new ArrayTest11();
		arr.push(new Object());
		arr.push(new Object());
		arr.push(new Object());
		arr.push(new Object());
		arr.push(new Object());
		arr.push(new Object());
		arr.push(new Object());
		arr.push(new Object());
		arr.push(new Object());
		arr.push(new Object());
		arr.push(new Object());
		
		arr.pop();
		arr.pop();
		arr.pop();
		arr.pop();
		arr.pop();
		arr.pop();
		arr.pop();
		arr.pop();
		arr.pop();
		arr.pop();
		arr.pop();
	}

	private Object[] elements;
	private int index;
	//private int index = 0;//表示栈帧指向了顶部元素的上方
	//private int index = -1;//表示栈帧指向了顶部元素
	
	public ArrayTest11() {
		this.elements = new Object[10];
		this.index = -1;
	}
	
	public void push(Object obj) {
		if(this.index >= this.elements.length - 1) {
			System.out.println("压栈失败,栈已满!");
			return ;
		}
		
		index++;
		elements[index] = obj;
		System.out.println("压栈成功");
	}
	
	public void pop(){
		if(index < 0) {
			System.out.println("弹栈失败,栈已空!");
			return;
		}
		
		System.out.println("弹栈成功,元素为:" + elements[index]);
		index--;
		
	}

	public int getIndex() {
		return index;
	}

	public void setIndex(int index) {
		this.index = index;
	}

	public Object[] getElements() {
		return elements;
	}

	public void setElements(Object[] elements) {
		this.elements = elements;
	}
}

运行结果:

压栈成功
压栈成功
压栈成功
压栈成功
压栈成功
压栈成功
压栈成功
压栈成功
压栈成功
压栈成功
压栈失败,栈已满!
弹栈成功,元素为:java.lang.Object@15db9742
弹栈成功,元素为:java.lang.Object@6d06d69c
弹栈成功,元素为:java.lang.Object@7852e922
弹栈成功,元素为:java.lang.Object@4e25154f
弹栈成功,元素为:java.lang.Object@70dea4e
弹栈成功,元素为:java.lang.Object@5c647e05
弹栈成功,元素为:java.lang.Object@33909752
弹栈成功,元素为:java.lang.Object@55f96302
弹栈成功,元素为:java.lang.Object@3d4eac69
弹栈成功,元素为:java.lang.Object@42a57993
弹栈失败,栈已空!

/*

  • 为某个酒店编写程序:酒店管理系统,模拟订房、退房、打印所有房间状态等功能
  • 1.该系统的用户是:酒店前台
  • 2.酒店使用一个二维数组来模拟
  • 3.酒店中的每个房间应该是一个Java对象:Room
  • 4.每一个房间应该有:房间编号、房间类型、房间是否空闲
  • 5.系统应该对外提供的功能:
  • 可以预定房间:用户输入房间编号,订房
  • 可以退房:用户输入房间编号,退房
  • 可以查看所有房间的状态:用户输入某个指令应该可以查看所有房间状态
    */
package javaCoreTest;

import java.util.Scanner;



public class ArrayTest12 {

	public static void main(String [] args) {
		Hotel hotel = new Hotel();
		/**
		 * 输入欢迎界面
		 */
		System.out.println("欢迎使用酒店管理系统,请认真阅读以下使用说明");
		System.out.println("功能编号对应的功能:1表示查看房间列表,2表示订房,3表示退房,0表示退出系统");
		Scanner in = new Scanner(System.in);
		
		while(true) {
			System.out.println("请输入功能编号:");
			int i = in.nextInt();
			
			if(i == 1) {
				hotel.print();
			}else if(i == 2){
				System.out.println("请输入房间编号:");
				int roomNo = in.nextInt();
				hotel.order(roomNo);
			}else if(i == 3) {
				System.out.println("请输入房间编号:");
				int roomNo = in.nextInt();
				hotel.exit(roomNo);
			}else if(i == 0) {
				System.out.println("再见,欢迎下次再来!");
				return;
			}else {
				System.out.println("输入功能有误,请重新输入");
				
			}
		}
		
	}
}

class Room{
	/**
	 * 房间编号:
	 * 1楼:101 102 103 104 105 106
	 * 2楼:201 202 203 204 205 206
	 * 3楼:301 302 303 304 305 306
	 */
	private int no;
	

	/**
	 * 房间类型:标准间 单人间 总统套房
	 */
	private String type;
	
	/**
	 * 房间状态:
	 * true表示空闲,房间可以被预定
	 * false表示占用,房间不能被预定
	 */
	private boolean status;
	
	public Room(int no, String type, boolean status) {
		this.no = no;
		this.type = type;
		this.status = status;
	}
	
	public int getNo() {
		return no;
	}

	public void setNo(int no) {
		this.no = no;
	}

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	//IDE工具对于boolean类型的变量,生成的get方法的方法名是:isXxx()
	public boolean isStatus() {
		return status;
	}

	public void setStatus(boolean status) {
		this.status = status;
	}
	
	//重写equals方法
	public boolean equals (Object obj) {
		if(obj == null || !(obj instanceof Room))return false;
		if(this == obj) return true;
		
		Room room = (Room)obj;
		return this.no == room.no;
	}
	
	//重写toString方法
	public String toString() {
		return  "[" + no + "," +  type + "," + (status ? "空闲" : "占用") + "]";
	}
	
}

class Hotel{
	/**
	 * 二维数组,模拟酒店所有房间
	 */
	private Room [][] rooms ;
	
	public Hotel(){
		//动态初始化
		rooms = new Room[3][10];
		
		for(int i = 0; i < rooms.length; i++) {
			for(int j = 0; j < rooms[i].length; j++) {
				if(i == 0) {
					rooms[i][j] = new Room((i+1)*100+j+1, "单人间", true);
				}
				
				if(i == 1) {
					rooms[i][j] = new Room((i+1)*100+j+1, "双人间", true);
				}
				
				if(i == 2) {
					rooms[i][j] = new Room((i+1)*100+j+1, "总统套房", true);
				}
			}
		}
	}
	
	public void print() {
		for(int i = 0; i < rooms.length; i++) {
			for(int j = 0; j < rooms[i].length; j++) {
				Room room = rooms[i][j];
				System.out.print(room.toString());
			}
			System.out.println();
		}
	}
	
	/**
	 * 订房方法:
	 * 调用此方法时需要传递一个房间编号。这个房间编号由前台小姐姐输入
	 */
	public void order(int roomNo) {
		Room room = rooms[roomNo/100 - 1][roomNo%100 - 1];
		room.setStatus(false);
		System.out.println(roomNo + "已订房");
	}
	
	/**
	 * 退房方法
	 */
	public void exit(int roomNo) {
		Room room = rooms[roomNo/100 - 1][roomNo%100 - 1];
		room.setStatus(true);
		System.out.println(roomNo + "已退房");
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值