数组Array及其工具类的使用

一、一维数组

(一)初始化

1、静态初始化:给出初始值,系统决定长度

int[] sArr = {1,2,3};
String[] sArrStr = {"a","b","c"};

2、动态初始化:只指定长度,系统给出初始值

int[] dArr = new int[3];//分配空间
dArr[0] = 1;
dArr[1] = 2;
dArr[2] = 3;
		
String[] dArrStr = new String[4];//分配空间

3、赋值操作:引用值的指向

	public void test2(){		
		int[] arr1= new int[2];
		arr1[0]= 0;
		arr1[1]= 1;
		System.out.println(arr1[0]);// 0
		System.out.println(arr1[1]);// 1
		
		System.out.println("*****************************");
		
		int[] arr2 = arr1;//相当于把数组1的地址同样给了数组2
		arr2[0] = 100;
		arr2[1] = 200;
		
		System.out.println(arr1[0]);//100
		System.out.println(arr1[1]);//200
		
		System.out.println(arr2[0]);//100
		System.out.println(arr2[1]);//200
		
	}

(二)内存分配

1、一个数组

数组Array及其工具类的使用_第1张图片

2、多个数组:注意引用值的拷贝

数组Array及其工具类的使用_第2张图片

(三)常见操作

1、遍历:几乎所有数组的操作,都是可以用循环解决的。
	/**
	 * 循环操作
	 */
	public void test3(){
		
		int[] arr = {298,2,14,345,256,89,100,7};
		
		//循环操作1
		int len = arr.length;
		for (int i = 0; i < len; i++) {
			System.out.println(arr[i]);
		}
		
		System.out.println("-----------------------");
		
		//循环操作2
		for (int i : arr) {
			System.out.println(i);
		}
	}

 
2、获取最值:预定索引【0】是最大,循环,比较。
	/**
	 * 获取最值
	 */
	public void test4(){
		int[] arr = {298,2,14,345,256,89,100,7};
		
	
		int max = arr[0];
		for (int i = 1; i < arr.length; i++) {
			max = max > arr[i] ? max : arr[i];
		}
		System.out.println("数组中最大的值 :  "+max);
		
	}
3、数组元素逆序:
	/**
	 * 数组元素逆序
	 * [298, 2, 14, 345, 256, 89, 100, 7]
	 * [7, 100, 89, 256, 345, 14, 2, 298]
	 */
	public void test5(){
		int[] arr = {298,2,14,345,256,89,100,7};
		
		// 方法一:0和(length-1),1和((length-1-1)一次类推
		for (int i = 0; i < arr.length/2; i++) {
			int temp = arr[i];
			arr[i] = arr[arr.length-1-i];
			arr[arr.length-1-i] = temp;
		}

		
		//方法二
		for (int start = 0,end=arr.length-1; start <= end; start++,end--) {
			int temp = arr[start];
			arr[start] = arr[end];
			arr[end] = temp;
		}
	}

 
4、数组查表法
	/**
	 * 数组查表法
	 */
	public void test6(){
		
		String[] strArr = {"星期一","星期二","星期三","星期四","星期五","星期六","星期日"};
		
		Scanner sc = new Scanner(System.in);//得到键盘输入
		int index = sc.nextInt();
		System.out.println("你要找的日期为 :  " + strArr[index]);
	}
5、数组元素查找:基本查找,Arrays提供了二分查找。
	/**
	 * 数组元素查找
	 */
	public void test7(){
		
		int[] indexArr = {1,2,3,4,5,3};
		int task = 3;
		
		//基本查找
		for (int i = 0; i < indexArr.length; i++) {
			if(task == indexArr[i]){
				System.out.println("下标为: " + i);
				break;//加break的话,只取到第一次出现的索引
			} 
			
		}
		
		System.out.println(Arrays.binarySearch(indexArr, 3));//二分查找
	}

 
6、int类型数据转换为数组*
	/**
	 * int数据转成数组
	 */
	public static void jiamiDemo(){
		//int数据转成数组
		int number =1234567;//定义数据
		int len = 8;
		int[] arr = new int[len];//定义数组
		
		//把数据中每一位上的数据获取后存储到数组中
//		int index = 0;
//		arr[index] = number%10;
//		index++;
//		arr[index] = number/10%10;
//		.
//		.

		//利用取余获取每一位上的值
		int index = 0;
		while(number > 0) {
			arr[index] = number%10;
			index++;
			number/=10;//一次获取位数的值
		}
		
		for (int i = 0; i < index; i++) {
			System.out.print(arr[i]);
		}
		
	}

 
7、数组的拷贝
1)简单拷贝:注意浅拷贝与深拷贝的区别
	/**
	 * 简单拷贝
	 */
	public void test8() {
		
		String[] arr = {"a","b","a","b","a4","b5"};
		String[] copyArr;
		
		// 浅拷贝:地址值(引用值).
		// 即arr与copyArr指向【堆】同一个数组
		copyArr = arr;
		arr[3] = "9999999999";//指向同一个地址,修改arr,copyArr也会改变
		System.out.println(Arrays.asList(copyArr));
		
		// 深拷贝,指向不同的引用:
		// 方法一:循环
		copyArr = new String[arr.length];
		for (int i = 0; i < arr.length; i++) {
			copyArr[i] = arr[i];
		}
		arr[3] = "改值";//修改arr不影响
		System.out.println(Arrays.asList(copyArr));
		
		// 方法二:clone。
		copyArr = arr.clone();
		arr[2] = "22222";//修改不影响
		System.out.println(Arrays.asList(copyArr));
		
		// 方法三:arraycopy()。
//		copyArr = new String[arr.length];//不new 一个,则是浅拷贝;new一个则为深拷贝。
		System.arraycopy(arr, 0, copyArr, 0, arr.length);
		arr[2] = "22222888";
		System.out.println(Arrays.asList(copyArr));
		
		
		// 方法四:Arrarys类的copyOf()方法与copyOfRange()方法可实现对数组的复制
		copyArr = Arrays.copyOf(arr, arr.length);
		copyArr = Arrays.copyOfRange(arr, 0, arr.length);
		arr[4] = "12345";
		System.out.println(Arrays.asList(copyArr));
		
	}

 
2)复杂拷贝:这道题以前在“科沃斯(苏州)”被面试过。
	/**
	 * 数组的拷贝
	 * 1,2 拷贝到 3
	 */
	public void test9(){
		
		String[] arr = {"a","b","a","b"};
		String[] arr2 = {"1","2","3"};
		
		int len = arr.length;
		int len2 = arr2.length;
		
		String[] copyArr = new String[len+len2];
		
		// 方法一:使用System.arraycopy()方法
		System.arraycopy(arr, 0, copyArr, 0, len);
		System.arraycopy(arr2, 0, copyArr, len, len2);
		
		
		// 方法二:循环
		for (int i = 0; i < len; i++) {
			copyArr[i] = arr[i];
		}
		for (int i = 0; i < len2; i++) {
			copyArr[len+i] = arr2[i];
		}
		System.out.println(Arrays.asList(copyArr));
		
		// 方法三:ArrayList
		List list = new ArrayList();
		for (int i = 0; i < len; i++) {
			list.add(arr[i]);
		}
		for (int i = 0; i < len2; i++) {
			list.add(arr2[i]);
		}
		
		Object [] aa = list.toArray();//利用List的toArray()方法
		
		System.out.println(Arrays.asList(aa));

	}

 

二、二维数组

(一)初始化

1、动态初始化

1)格式1

int[][] arr = new int[3][2];

2)格式2

int[][] arr2 = new int[2][]; 
arr2[0] = new int[2];
arr2[1] = new int[3];

2、静态初始化

int[][]arr3 = {{1,2},{3,4,5}};

(二)内存图解

1、动态初始化1

  • 3个一维数组,每个一维数组有2个元素。
  • 分配空间,存在地址值。二维数组中一维数组,默认为空。等每个一维数组构造完毕,才会分配空间,附上引用值。
  • Java中没有二维数组的概念,其实二维数组就是一维数组组成的,存放的是引用值。
  • 即会有两类引用值,二维的引用值赋予【栈】内存,一维的引用赋予二维。
数组Array及其工具类的使用_第3张图片

2、动态初始化2

数组Array及其工具类的使用_第4张图片

3、静态初始化:自动会new一维数组。

数组Array及其工具类的使用_第5张图片

(三)简单操作

1、遍历:二次循环
	/**
	 * 遍历
	 */
	private void test2() {
		int[][] arr = {{1,2},{3,4,5},{6,7,8,9}};
		for (int i = 0; i < arr.length; i++) {
			for (int j = 0; j < arr[i].length; j++) {
				System.out.print(arr[i][j] + " ");
			}
			System.out.println();
		}
		
		System.out.println("*****************************************************8");
	
	}
2、求和
	/**
	 * 求和
	 */
	private void test3() {
		int[][] arr = {{1,2},{3,4,5},{6,7,8,9}};
		int sum = 0;
		for (int i = 0; i < arr.length; i++) {
			for (int j = 0; j < arr[i].length; j++) {
				sum += arr[i][j];
			}
		}
		System.out.println("求和:  " + sum);
	}

 
3、杨辉三角

	/**
	 * 杨辉三角
	 * 任何一行的第一列和最后一列都是1
	 * 从第三行开始,每一个数据时它上一行的前一列和它上一行的本列之和,最后一列除外。
	 * 1
	 * 1 1
	 * 1 2 1
	 * 1 3 3 1
	 * 1 4 6 4 1
	 * 1 5 10 10 5 1
	 */
	public void test4(){
		//创建键盘录入对象
		Scanner scanner = new Scanner(System.in);
		
		// 这个n的数据来自键盘录入
		int n = scanner.nextInt();
		
		//定义一个二维数组
		int[][] arr = new int[n][n];
		
		// 给这个二维数组任何一行的第一列和最后一列赋值1
		for (int i = 0; i < arr.length; i++) {
			arr[i][0] = 1;//任何一行第1列
			arr[i][i] = 1;//任何一行最后1列
		}
		
		// 从第三行开始,每一个数据时它上一行的前一列和它上一行的本列之和,最后一列除外。
		// 第3行,第2列开始,所以i=2,j=1开始
		for (int i = 2; i < arr.length; i++) {
			// 不能取最后一列,所以减去1,j <= i-1
			for (int j = 1; j <= i-1; j++) {
				arr[i][j] = arr[i-1][j-1] + arr[i-1][j];
			}
		}
		
		//遍历二维数组
		for (int i = 0; i < arr.length; i++) {
			for (int j = 0; j <= i; j++) {
				System.out.print(arr[i][j]+" ");
			}
			System.out.println();
		}
		
	}

三、数组高级

(一)排序算法(介绍被面试过的2种)

1、冒泡排序(被面到过好几次,如上海安硕(信贷系统)、科沃斯)

1)原理:相邻元素两两比较,大的往后放,第一次完毕,最大值出现在了最大索引处。同理,继续,即可得到一个排好序的数组。

  • 两两比较,大的往后放
  • 总共需要比较数组长度的 -1 次。(外层循环)
  • 每一个比较完毕后,下一次比较的时候就会少一个元素的比较(内层循环)

2)分析图:

数组Array及其工具类的使用_第6张图片

3)代码实现

	/**
	 * 冒泡排序:
	 * 数组排序之冒泡排序:
     * 		相邻元素两两比较,大的往后放,第一次完毕,最大值出现在了最大索引处
     * 
     * 外循环:一共是 arr.length-1 次循环循环
     * 内循环:每次循环都会少一次
     * 
     * 两两比较,大的往后放
	 * 总共需要比较数组长度的 -1 次。(外层循环)
	 * 每一个比较完毕后,下一次比较的时候就会少一个元素的比较(内层循环)
	 */
	private void test1() {
		// 定义一个数组
		int[] arr = { 24, 69, 80, 57, 13 };
		System.out.println("排序前:");
		printArray(arr);
		
		// 第一次比较
		// arr.length - 1是为了防止数据越界
		// arr.length - 1 - 0是为了减少比较的次数
/*		for (int x = 0; x < arr.length - 1 - 0; x++) {
			if (arr[x] > arr[x + 1]) {
				int temp = arr[x];
				arr[x] = arr[x + 1];
				arr[x + 1] = temp;
			}
		}
		System.out.println("第一次比较后:");
		printArray(arr);*/
		
		// 第二次比较
		// arr.length - 1是为了防止数据越界
		// arr.length - 1 - 1是为了减少比较的次数
/*		for (int x = 0; x < arr.length - 1 - 1; x++) {
			if (arr[x] > arr[x + 1]) {
				int temp = arr[x];
				arr[x] = arr[x + 1];
				arr[x + 1] = temp;
			}
		}
		System.out.println("第二次比较后:");
		printArray(arr);*/
		
		//排序
/*		for (int x = 0; x < arr.length - 1; x++) {
			for (int y = 0; y < arr.length - 1 - x; y++) {
				if (arr[y] > arr[y + 1]) {
					int temp = arr[y];
					arr[y] = arr[y + 1];
					arr[y + 1] = temp;
				}
			}
		}*/
		
		for (int i = 0; i < arr.length-1; i++) {//总共需要比较数组长度的 -1 次。(外层循环)
			for (int j = 0; j < arr.length-1-i; j++) {//每一个比较完毕后,下一次比较的时候就会少一个元素的比较(内层循环)
				if(arr[j] > arr[j+1]){
					int temp = arr[j]; 
					arr[j] = arr[j+1];
					arr[j+1] = temp;
				}
			}
		}
		
		System.out.println("冒泡排序后:");
		printArray(arr);
	}

2、选择排序

1)原理:从0索引开始,依次和后面元素比较,小的往前放,第一次完毕,最小值出现在了最小索引处
  • 从0索引开始,依次和后面元素比较,小的往前放
    • 第一次是从 0 索引开始和其他元素比较
    • 第二次是从 1 索引开始和其他元素比较
    • 最后一次是数组长度-2 的元素 和数组长度-1的元素比较

2)分析图

数组Array及其工具类的使用_第7张图片

3)代码实现

	/**
	 * 选择排序
	 * 		从0索引开始,依次和后面元素比较,小的往前放,第一次完毕,最小值出现在了最小索引处
	 */
	private void test2() {
		
		// 定义一个数组
		int[] arr = { 24, 69, 80, 57, 13 };
		System.out.println("排序前:");
		printArray(arr);
		
		/*
		// 第一次
		int x = 0;
		for (int y = x + 1; y < arr.length; y++) {
			if (arr[y] < arr[x]) {
				int temp = arr[x];
				arr[x] = arr[y];
				arr[y] = temp;
			}
		}
		System.out.println("第一次比较后:");
		printArray(arr);

		// 第二次
		x = 1;
		for (int y = x + 1; y < arr.length; y++) {
			if (arr[y] < arr[x]) {
				int temp = arr[x];
				arr[x] = arr[y];
				arr[y] = temp;
			}
		}
		System.out.println("第二次比较后:");
		printArray(arr);
		*/
		
		for (int i = 0; i < arr.length-1; i++) {//从0索引开始,
			for (int j = i+1; j < arr.length; j++) {//依次和后面元素比较,
				if(arr[j] < arr[i] ){//小的往前放
					int temp = arr[i]; 
					arr[i] = arr[j];
					arr[j] = temp;
				}
			}
		}
		
		printArray(arr);
		
	}

3、实例操作:把字符串中的字符进行排序。

	/*
	 * 把字符串中的字符进行排序。
	 * 		举例:"dacgebf"
	 * 		结果:"abcdefg"
	 * 
	 * 分析:
	 * 		A:定义一个字符串
	 * 		B:把字符串转换为字符数组
	 * 		C:把字符数组进行排序
	 * 		D:把排序后的字符数组转成字符串
	 * 		E:输出最后的字符串
	 */
	private void test3() {
		
		String str = "mkloiuytrfdgsa";
		
		char[] strArr = str.toCharArray();
		
		//选择排序
/*		for (int i = 0; i < strArr.length-1; i++) {//从0索引开始,
			for (int j = i+1; j < strArr.length; j++) {//依次和后面元素比较,
				if(strArr[j] < strArr[i]) {//小的往前放
					char temp = strArr[j];
					strArr[j] = strArr[i];
					strArr[i] = temp;
				}
			}
		}*/
		
		
		//冒泡排序
		for (int i = 0; i < strArr.length-1; i++) {//每次从0开始,一共是length-1次
			for (int j = 0; j < strArr.length-1-i; j++) {//每次就会少一次
				if(strArr[j] > strArr[j+1]) {//大的往后放
					char temp = strArr[j+1];
					strArr[j+1] = strArr[j];
					strArr[j] = temp;
				}
			}
		}
		
		String sortStr = String.valueOf(strArr);
		System.out.println(sortStr);//adfgiklmorstuy
		
	}

(二)查找算法

1、基本查找算法

1)对象:针对没有顺序的数组

2)方法:循环整个数组,依次比较
3)代码实现:

	/**
	 * 查找
	 * 		基本查找:数组元素无序(从头找到尾)
	 */
	private void test4() {
		//定义一个数组
		int[] arr = {55,22,11,44,33,88,66};//没顺序的数组
		
		int a = 33;
		int index = -1;
		for (int i = 0; i < arr.length; i++) {//循环整个数组,依次比较
			if(arr[i]==a) {
				System.out.println("索引为" + i);
				index = i;
				break;
			}
		}
		
		if(index == -1){
			System.out.println("没找到....");
		}
	}

2、二分查找算法

1)对象:针对有顺序的数组

2)方法:
  • 拿中间索引的值和要查找的值进行比较,相等,就返回当前的中间索引 。
  • 大,左边找  max = mid - 1; (中间值大,向左找;这时最大值为这个(中间值-1),最小值为0)
  • 小,右边找  min = mid + 1; (中间值小,向右找;这时最大值为(length -1),最小值为(中间值+1))
  • 再计算中间索引,然后再比较。
3)分析图:
数组Array及其工具类的使用_第8张图片
4)代码实现
	/**
	 * 二分查找
	 *  * 分析:
	 * 		A:定义最大索引,最小索引
	 * 		B:计算出中间索引
	 * 		C:拿中间索引的值和要查找的值进行比较
	 * 			相等:就返回当前的中间索引
	 * 			不相等:
	 * 				大	左边找
	 * 				小	右边找
	 * 		D:重新计算出中间索引
	 * 			大	左边找
	 * 				max = mid - 1;
	 * 			小	右边找
	 * 				min = mid + 1;
	 * 		E:回到B
	 */
	public void test5() {
		int[] arr = {11,22,33,44,55,66,77};
		int value = 0;
		//定义最大索引,最小索引
		int max = arr.length -1;
		int min = 0;
		
		//计算出中间索引
		int mid = (max +min)/2;
		
		//拿中间索引的值和要查找的值进行比较
		while(arr[mid] != value){
			if(arr[mid]>value){//中间值大,向左找;这时最大值为这个(中间值-1),最小值为0
				max = mid - 1;
			}else if(arr[mid] max){
				mid = -1;
				break;//找不到
			}
			mid = (max +min)/2;
		}
		System.out.println("二分查找后的结果:  "+ mid);
	}

 

5)注意问题:一个无序数组,先排序,再使用二分查找,这是不行的。

  • 因为数组本身是无序的,所以这种情况下的查找不能使用二分查找。
  • 因为先排序后,已经改变了最原始的元素索引,再查找出来的索引不是原有数组的索引值了。
package array;
/**
 * 
 * @Title: 使用二分排序的问题
 * @Description:
 * @Copyright: Copyright (c) 2015
 * @Company: 
 *
 * @author: SAM-SHO
 * @version: 1.0
 * @CreateDate:Apr 9, 2015
 */
/*
 * 注意:下面这种做法是有问题的。
 * 因为数组本身是无序的,所以这种情况下的查找不能使用二分查找。
 * 你先排序了,但是你排序的时候已经改变了我最原始的元素索引,所以查找出来的不是原有需要的索引了。
 */
public class ArrayDemo2 {
	public static void main(String[] args) {
		// 定义数组
		int[] arr = { 24, 69, 80, 57, 13 };

		// 先排序
		bubbleSort(arr);
		// 后查找
		int index = getIndex(arr, 80);
		System.out.println("index:" + index);
	}

	// 冒泡排序代码
	public static void bubbleSort(int[] arr) {
		for (int x = 0; x < arr.length - 1; x++) {
			for (int y = 0; y < arr.length - 1 - x; y++) {
				if (arr[y] > arr[y + 1]) {
					int temp = arr[y];
					arr[y] = arr[y + 1];
					arr[y + 1] = temp;
				}
			}
		}
	}

	// 二分查找
	public static int getIndex(int[] arr, int value) {
		// 定义最大索引,最小索引
		int max = arr.length - 1;
		int min = 0;

		// 计算出中间索引
		int mid = (max + min) / 2;

		// 拿中间索引的值和要查找的值进行比较
		while (arr[mid] != value) {
			if (arr[mid] > value) {
				max = mid - 1;
			} else if (arr[mid] < value) {
				min = mid + 1;
			}

			// 加入判断
			if (min > max) {
				return -1;
			}

			mid = (max + min) / 2;
		}

		return mid;
	}
}

 

(三)数组工具类

1、Arrays

1)把数组转成字符串:public static String toString(int[] a) 

2)对数组进行排序:public static void sort(int[] a) 
  • 内部使用快速排序
3)二分查找:public static int binarySearch(int[] a,int key) 
4)数组复制:copyOf 和 copyOfRange
package array;

import java.util.Arrays;

/**
 * 
 * @Title: Arrays工具类的使用
 * @Description:
 * @Copyright: Copyright (c) 2015
 * @Company: 
 *
 * @author: SAM-SHO
 * @version: 1.0
 * @CreateDate:Apr 9, 2015
 */
/*
 * Arrays:针对数组进行操作的工具类。比如说排序和查找。
 * 1:public static String toString(int[] a) 把数组转成字符串
 * 2:public static void sort(int[] a) 对数组进行排序
 * 3:public static int binarySearch(int[] a,int key) 二分查找
 */
public class ArraysDemo {
	public static void main(String[] args) {
		// 定义一个数组
		int[] arr = { 24, 69, 80, 57, 13 };

		// public static String toString(int[] a) 把数组转成字符串
		System.out.println("排序前:" + Arrays.toString(arr));

		// public static void sort(int[] a) 对数组进行排序
		Arrays.sort(arr);
		System.out.println("排序后:" + Arrays.toString(arr));

		// [13, 24, 57, 69, 80]
		// public static int binarySearch(int[] a,int key) 二分查找
		System.out.println("binarySearch:" + Arrays.binarySearch(arr, 57));
		System.out.println("binarySearch:" + Arrays.binarySearch(arr, 577));
		
		
	}
}

2、Array-反射使用

你可能感兴趣的:(冒泡排序,快速排序,二分查找,数组,arrray)