数组 java

一维数组

  • java语言中的数组是一种引用数据类型,不属于基本数据类型,父类是Object
  • 数组实际上相当于一个容器,可以同时存储多个元素
  • 数组当中可以存储“基本数据类型”,也可以存储“引用数据类型”的数据
  • 数组是引用数据类型,所以数组对象在堆内存当中存储。如果数组当中存储的是java对象的话,实际上存储的是对象的引用(内存地址)
  • 数组一旦创建,java规定,长度不再改变。
  • 数组的分类:一维数组、二维数组、三维数组、多维数组
  • 每个数组对象都有length属性,用于获取数组中元素的个数。数组每个元素都是有下标的,以0开始,以1递增,最后一个元素为length-1。对于元素的存取操作都需要通过下标来进行操作
  • java要求数组中元素的类型统一,int类型数组只能存储int类型
  • 数组存储的特点:数组中的元素的内存地址的连续的,数组中首元素的内存地址,作为整个数组的内存地址。
  • 优点:查询检索某个下标的元素时,效率极高
    • 每一个元素的内存地址在空间存储上都是连续的
    • 每一个元素类型相同,所以占用空间大小一致
    • 知道第一个元素的内存地址,知道每一个元素占用的空间大小,知道所求的下标,所以通过一个数学表达式就可以计算出某个下标上元素的内存地址,直接通过内存地址定位元素。
  • 缺点
    • 由于数组中内存地址是连续的,进行增删数组元素的时候【除最后一个元素】,需要将之后的所有元素向前或者向后移动
    • 数组不能存储大量数据,因为很难在内存空间上找到一块特别大的连续的内存空间。
      在这里插入图片描述

数组java

  • 声明一维数组

    • int[] array;
    • double[] array;
    • boolean[] array;
    • String[] array;
    • Object[] array;
  • 初始化一维数组

    • 静态初始化
      • int[] arry ={100,20,30,40,50}
    • 动态初始化【先开空间】 ——例题一
      • int[] array=new int[5];//5代表数组的元素个数,初始化一个5个长度的int类型的数组,每个元素默认值为0
  • 当一个方法的参数是一个数组的时候,进行传参——见例二

数组基础操作

package datastructure.array;

public class ArrayTest01 {
	public static void main(String[] args) {
		int[] a1= {1,2,3,4,4,6,7,8};
				//下标0 1 2 3 4 5 6 7
		//所有数组对象都有length属性!!属性!!!
		System.out.println("a1数组中元素的个数"+a1.length);
		
		//利用下标对元素进行读取操作
		System.out.println("第一个元素"+a1[0]);
		System.out.println("最后一个元素"+a1[a1.length-1]);
		
		//利用数组下标对元素进行修改操作
		a1[0]=110;
		a1[a1.length-1]=120;
		
		//数组遍历
		for(int i =0;i<a1.length;i++) {
			System.out.print(a1[i]+"\t");
		}
		System.out.println();
		//下标越界 异常	ArrayIndexOutOfBoundsException
		//System.out.println(a1[10]);
		//倒序遍历
		for(int i =a1.length-1 ;i>=0;i--) {		//最大下标数:a1.length-1
			System.out.print(a1[i]+"\t");
		}
	}
}

例题一

package datastructure.array;

public class ArrayTest02 {
	public static void main(String[] args) {
		int[] a = new int[4];
		
		//动态方式创建Object类型数组
		Object[] objs =new Object[3];	//引用数据类型默认值为null
		for(int i = 0;i<objs.length;i++) {
			System.out.print(objs[i]+"\t");
		}
	}
}

在这里插入图片描述

例题二

package datastructure.array;

/**
 * @author 衣鱼
 *	当方法上一个参数的类型 是数组的时候
 *
 */
public class ArrayTest02 {
	public static void main(String[] args) {
		//调用方法时传一个数组
		int[] x1 = {0,1,2,3};
		printArray(x1);
		
		//动态初始化
		int[] x2=new int[4];
		printArray(x2);
		printArray(new int[3]);
	}
	
	//打印数组元素printArray()
	public static void printArray(int[] array) {
		for(int i = 0;i<array.length;i++) {
			System.out.print(array[i]+"\t");
		}
		System.out.println();
	}
}

main: String[] args

  • String[] args数组主要是用来接收用户的输入参数的。
    控制台输入abc sdf 12j,那么jvm自动将abc sdf 12j以空格的方式进行分离,分离完成之后,自动放到String[] args数组当中。即{“abc”,“sdf”,“12j”}
  • 模拟一个系统,假设这个系统需要输入用户名和密码才能使用
    • 运行代码时,接收用户输入设置,如图所示,在arguments栏中的program argument框中输入需要传入的参数。
      在这里插入图片描述
      在这里插入图片描述

例题三

package datastructure.array;

/**
 * @author 衣鱼
 *	main 方法详解
 *	模拟一个系统,假设这个系统需要输入用户名和密码才能使用
 */
public class ArrayTest03 {
	/*//mian方法是jvm负责调用,jvm调用的时候一定会传一个String的数组
	public static void main(String[] args) {
		//jvm默认传递过来的数组长度默认是0
		System.out.println("jvm传递的String数组参数长度为"+args.length);
		//String[] args 什么时候会有值呢? 用户在控制台输入参数,这个参数自动会被转换为String[] args	
	}
	 */
	
	//用户名和密码输入String[] args数组当中
	public static void main(String[] args) {
		if(args.length!=2) {
			System.out.println("使用该系统时,请输入程序参数,参数中包括用户名和密码信息.例如:bob 123");
			return;
		}
		//程序执行到此说明用户确实提供用户名和密码
		//之后需要判断用户名和密码是否正确
		//取出用户名
		String username = args[0];
		//取出密码
		String password = args[1];
		//判断用户名和密码是否匹配
		//if(username.equals("衣鱼")&&password.equals("2580")) {		//容易空指针异常 username为null
		if("衣鱼".equals(username)&&"2580".equals(password)) {	//即使输入的字符串为空,也不会空指针异常
			System.out.println("登录成功!欢迎"+username+"回来");
			System.out.println("系统正为您更新");
		}
		else {
			System.out.println("您输入的密码错误,请检查密码!或者该用户不存在!");
		}
	}

}

一维数组:存储引用类型元素

  • 数组的存储类型:引用数据类型
  • 数组中存储的元素是引用,是java对象的内存地址。
  • 存放父类型的数组,可以存放子类型数据 Animal Cat Brid
  • 数组取出的元素可能是cat,也可能是brid。但是调用的方法都是父类共有的,属于animal,不需要向下转型
  • 如果想调用子对象特有方法,需要向下转型。
    在这里插入图片描述

例题四

package datastructure.array;

/**
 * @author 衣鱼
 *	一维数组的深入
 *		数组的存储类型:引用数据类型
 *		数组中存储的元素是引用,是java对象的内存地址。
 */
public class ArrayTest04 {
	public static void main(String[] args) {
		//创建animal类型的数组
		Animal a1= new Animal();
		Animal a2= new Animal();
		Animal[] animals= {a1,a2};
		//遍历
		for(int i =0;i<animals.length;i++) {
			//Animal a = animals[i];
			//a.move();
			animals[i].move(); 	//代码合并
		}
		 
		//修改
		//Animal数组中只能存放Animal类型,不能存放product类型
		//animals[1]=new Product();
		animals[1]=new Cat();		//存放父类型的数组,可以存放子类型数据
		
		//查看
		Animal[] ani = {new Cat(),new Brid()};
		for(int i = 0;i<ani.length;i++) {
			//ani[i]取出的可能是cat,也可能是brid。但是调用的方法都是父类共有的,属于animal,不需要向下转型
			Animal b = ani[i];		
			b.move();
			//如果想调用子对象特有方法,需要向下转型。
			if(ani[i] instanceof Cat) {		//ani[i]是Cat类的一个实例吗
				Cat c = (Cat)ani[i];
				c.catchMouse();
			}
			else if(ani[i] instanceof Brid) {
				Brid d =(Brid)ani[i];
				d.sing();
			}
		}
			
	}
}

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

class Cat extends Animal{
	public void move () {
		System.out.println("cat move!");
	}
	//猫特有方法
	public void catchMouse(){
		System.out.println("cat catch mouse!");
	}
}

class Brid extends Animal{
	public void move() {
		System.out.println("brid fly!");
	}
	//鸟特有方法
	public void sing() {
		System.out.println("brid sing !");
	}
}

数组扩容

  • 数组的扩容:在java开发中,数组的长度一旦确定是不可变的,数组满了,就需要扩容
  • 扩容思路:新建一个大容量的数组,然后将小容量的数组中的数据逐个拷贝到大容量数组当中。【套娃】
    结论:数组的扩容效率低,涉及到拷贝问题,这就需要开发人员预估计数组的大小。
    在这里插入图片描述

例题五

package datastructure.array;

/**
 * @author 衣鱼
 *	数组的扩容:在java开发中,数组的长度一旦确定是不可变的,数组满了,就需要扩容
 *	扩容思路:新建一个大容量的数组,然后将小容量的数组中的数据逐个拷贝到大容量数组当中。【套娃】
 *		结论:数组的扩容效率低,涉及到拷贝问题,这就需要开发人员预估计数组的大小。
 */
public class ArrayTest05 {
	public static void main(String[] args) {
		//java中数组的拷贝工作
		int[] src = {1,2,3,4,5,6};
		int[] dest =new  int[10];
		//将src的3,4,5复制到dest下标从4开始
		System.arraycopy(src, 2, dest, 4,3);
		
		//遍历数组
		for(int i =0;i<dest.length ;i++) {
			System.out.println(dest[i]);
		}
		
		//数组:引用数据类型扩容
		Object[] objs = {new Object(),new Object(),new Object()};
		Object[] destobjs= new Object[5];
		System.arraycopy(objs, 0, destobjs,0, objs.length);
		for(int i =0;i<destobjs.length ;i++) {
			System.out.println(destobjs[i]);
		}
	}
}


在这里插入图片描述

二维数组

  • 二维数组实际上是一种特殊的一维数组,这个特殊的一维数组当中的每一个元素都是一个一维数组
package datastructure.array;

/**
 * @author 衣鱼
 *	二维数组
 *
 */
public class ArrayTest06 {
	public static void main(String[] args) {
		//一维数组
		int[] array1 = {1,2,3,4};
		//二维数组
		int[][] array2 = {{},{},{}};		//每个元素都是特殊的一维数组
		//二维数组静态初始化
		int[][] array3 = {		//三个一维数组
				{11,12,13,14},
				{21,22,23,24,25},
				{31,32,33,34,35,36}
		};
		System.out.println(array3.length);  	//二维数组array3的长度为3
		System.out.println(array3[0].length); 		//array3[0]一维数组长度为4
		System.out.println("======================");
		//二维数组动态初始化
		//理解[][] 两个中括号代表意义
		int[][] array4 = new int[2][3];
		System.out.println(array4.length);  //2  有几个一维数组
		System.out.println(array4[1].length);  //3 第X个一维数组中的长度
																		//两行三列,有两个一维数组,每个一维数组有三个元素
		
		//取出array3第2个一维数组的第3个元素 ——23
		System.out.println("array3第2个一维数组的第3个元素是"+array3[1][2]);
		System.out.println("======================");
		//遍历二维数组
		for(int i =0 ;i<array3.length;i++) {
			for(int j =0;j<array3[i].length;j++) {
				System.out.print(array3[i][j]+"\t");
			}
			System.out.println();
		}
		//利用方法遍历
		printArray(array4);

	}
	//方法:遍历二维数组
	public static void printArray(int[][] array) {
		for(int i =0 ;i<array.length;i++) {
			for(int j =0;j<array[i].length;j++) {
				System.out.print(array[i][j]+"\t");
			}
			System.out.println();
		}
		
	}
}

算法

冒泡排序算法

package datastructure.array;
/**
 * @author 衣鱼
 * 原序列:9,6,5,2,8,3
 * 第一次排序  第一个位置的数:9  利用9排除最大泡
 *		9,6,5,2,8,3
 *		6,9,5,2,8,3
 *		6,5,9,2,8,3
 *		6,5,2,9,8,3
 *		6,5,2,8,9,3
 *		6,5,2,8,3,9		
 *
 *第二次排序  第一个位置的数:6  利用6排出余下的最大泡
 *		5,6,2,8,3
 *		5,2,6,8,3
 *		5,2,6,8,3 [6,8不需要交换]
 *		5,2,6,3,8
 *
 *第三次排序  第一个位置的数:5  利用5排出余下的最大泡
 *		2,5,6,3
 *		2,5,6,3
 *		2,5,3,6
 *
 *第四次排序  第一个位置的数:2  利用2排出余下的最大泡
 *		2,5,3
 *		2,3,5
 *
 *第五次排序  第一个位置的数:2  利用2排出余下的最大泡
 *		2,3
 *		
 */
public class BubbleSort {
	public static void main(String[] args) {
		int[] arr = {9,6,5,2,8,3,7,10,5,6,1};
		//冒泡排序
		//从左向右,依次比较,大数在右
		for(int i= arr.length-1;i>0;i--) {
			for(int j =0;j<i;j++) {
				if(arr[j]>arr[j+1]) {
					int x =arr[j];		//临时变量
					arr[j]=arr[j+1];
					arr[j+1]=x;
				}
			}
		}
		 PrintArray(arr);
	}
	
	//遍历函数
	public static void PrintArray(int[] array) {
		for(int i =0;i<array.length;i++) {
			System.out.print(array[i]+"\t");
		}
		System.out.println();
	}
}

选择排序算法

package datastructure.array;

/**
 * @author 衣鱼
 *		选择排序
 *			每次从这堆参与比较的数据中找出最小值
 *			将最小值和[参与比较的数据中]最前面的元素交换位置
 *			选择排序相比于冒泡排序的优点:每一次交换的位置都是有意义的。
 *		给学生按高矮排队,找出来班里面最矮的A,与第一个位置的同学交换位置。
 *		此时已经给A排好位置,A不属于待排集合里面,在剩下的同学里面,找出来最矮的同学,与待排集合的第一个位置的同学交换位置
 *		以此类推  n个同学,比较n-1次
 */
public class SelectSort {
	public static void main(String[] args) {
		int[] arr = {5,6,2,3,1,54,82,64,7,52,34,95};
		for(int i = 0;i<arr.length;i++) {
			for(int j =i+1;j<arr.length;j++) {
				//默认第i个下标最小
				if(arr[i]>arr[j]) {
					int temp =arr[i];
					arr[i]=arr[j];
					arr[j]=temp;
				}
			}
		}
		PrintArray(arr);
	}
	//遍历函数
		public static void PrintArray(int[] array) {
			for(int i =0;i<array.length;i++) {
				System.out.print(array[i]+"\t");
			}
			System.out.println();
		}
}

二分法查找

package datastructure.array;

import java.util.Arrays;

/**
 * @author 衣鱼
 *	查找数组内元素
 *		线性查找
 *		二分法查找
 *			二分法查找基于排序的基础之上
 *			二分法查找效率要高于线性查找
 *	
 *例:
 *	数组元素	20	30	40	50	60	70	80	90	100	110
 *	数组下标	0		1		2		3		4		5		6		7		 8		 9
 *	查找元素 70
 *		①首尾下标相加除以2,取整,得到中间下标	(0+9)/2 =4
 *		②找到下标为4的元素 60  ,比较60与待查找数据,60<70,说明70在60的右侧 ——要求有序
 *		③首尾下标相加除以2,取整,得到中间下标 【首变成中间下标+1: 4+1=5】(5+9)/2=7
 *		④找到下标为7的元素 90  ,比较90与待查找数据,90>70,说明70在90的左侧
 *		⑤首尾下标相加除以2,取整,得到中间下标 【尾变成中间下标-1】(5+6)/2 =5
 *		⑥找到70,返回数组下标
 */
public class ArraySearch {
	public static void main(String[] args) {
		int[] arr = {5,6,28,54,82,827,828,219,16,817,71,17,85};
		//arraySearch(arr,16);
		//排序
		Arrays.sort(arr);
		//有序遍历
		PrintArray(arr);
		//二分法查找
		binarySearch(arr,16);
		System.out.println(binarySearch(arr,16));
	}
	/**二分法查找
	 * */
	private static int binarySearch(int[] arr, int dest) {
		int begin =0;
		int end =arr.length-1;
		while(begin<=end) {				//难点:开始元素在结束元素的左侧就有机会继续循环!
			int mid =(begin+end)/2;
			if(arr[mid]==dest) {
				return mid;
			}else if(arr[mid]<dest) {
				//目标数据在中间数据在右侧
				begin=mid+1;
			}else{
				//(arr[mid]>dest)
				//目标数据在中间数据的左侧
				end =mid-1;
			}
		}
		return -1;
	}
	/**
	 * 线性查找数组内元素
	 * 	array 被查找的数组
	 * 	a 被查找的元素
	 * 	return i 返回匹配的元素的数组下标
	 * 	return -1 该数组没有该元素
	 * */
	public static int arraySearch(int[] array,int a) {
		for(int i = 0;i<array.length;i++) {
			if(array[i]==a) {
				return i;
			}
			//return -1;  //注意循环!
		}
		return -1;
	}
	
	//遍历函数
			public static void PrintArray(int[] array) {
				for(int i =0;i<array.length;i++) {
					System.out.print(array[i]+"\t");
				}
				System.out.println();
			}
	
	
}

Arrays工具类

  • Arrays类包含用来操作数组(比如排序和搜索)的各种方法
  • 二分法搜索,适用以下类型
    在这里插入图片描述
  • static int binarySearch(int[] a, int fromIndex, int toIndex, int key)
    使用二分搜索法来搜索指定的 int 型数组的范围,以获得指定的值。
  • static boolean equals(char[] a, char[] a2)
    如果两个指定的 char 型数组彼此相等,则返回 true。
  • static void fill(int[] a, int val)
    将指定的 int 值分配给指定 int 型数组的每个元素。
    • static void fill(int[] a, int fromIndex, int toIndex, int val)
      将指定的 int 值分配给指定 int 型数组指定范围中的每个元素。
  • static int hashCode(double[] a)
    基于指定数组的内容返回哈希码。
  • static void sort(long[] a, int fromIndex, int toIndex)
    对指定 long 型数组的指定范围按数字升序进行排序。
package datastructure.array;

import java.util.Arrays;

/**
 * @author 衣鱼
 *		java.util.Arrays; 工具类有很多方法,开发时可参考API的帮助文档
 */
public class ArraysTest02 {
	public static void main(String[] args) {
		int[] arr = {5,28,2,592,329,82,55,15,816,6,73,10,768};
		Arrays.sort(arr);
		//遍历
		for(int i = 0;i<arr.length;i++) {
			System.out.print(arr[i]+"\t");
		}
		System.out.println();
		//二分法查找
		int index =Arrays.binarySearch(arr, 768);
		System.out.println(index==-1?"该元素不存在":"该元素的下标为"+index);
	}
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值