数组就是相同数据的有序集合。
可以通过下标访问它们,而且是有序的。
数组的创建-
首先要声明数组变量,才能在程序中使用。
dataType[] array; dataType array[]; //虽然效果相同,但是建议用上面那种
-
java中使用new *** 作符创建数组
dataType[] array = new dataType[arraySize];
-
数组的元素通过下标访问,下标从零开始。
-
获取数组长度用:
arrays.length
通过for循环输入数组代码如下:
public class Demo01 { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int[] nums;//定义声明数组 int nums2[]; nums = new int[10];//创建和分配内存给数组 for (int i = 0; i < nums.length; i++) { nums[i]= scanner.nextInt();//输入时空格隔开 } for (int i = 0; i < nums.length ; i++) { System.out.print(nums[i]+" "); } } }内存分析
-
堆
存放new的对象和数组,可以被所有的线程共享,不会存放别的对象引用。
-
栈
存放基本变量类型(会包括这个基本类型的具体数值)
引用对象的变量(会存放这个引用在堆里的具体地址)
-
方法区
可以有所有的线程共享
包括了所有的class和static变量
数组过程:先在栈里声明一个数组,new的时候在堆里开辟内存空间。
public class ArrayDemo01 { public static void main(String[] args) { //静态初始化:创建 + 赋值 int[] a = {1,2,3,4,5,6,7,8}; System.out.println(a[0]); //动态初始化:包含默认初始化,默认初始化为0 int [] b = new int[10]; b[0] = 0; } }数组的特点
-
长度是确定的。一旦确定长度不可以改变。
-
元素都是相同的类型。
-
元素可以是任何数据类型,包括基本类型和引用类型。
八大基本数据类型:int、char、byte、long、short、float、double、boolean
-
数组变量属于引用类型,数组可以看成对象,数组中的每个元素相当于该对象的成员变量
数组本身就是对象,java中对象是在堆中的,数组对象本身是在堆中的。
下标区间:[0,length-1],越界会报错
ArrayIndexOutOfBoundsException:数组下标越界异常!
小结:- 数组是相同数据类型的有序集合。(可以是任何类型)
- 数组也是对象。数组元素相当于对象的成员元素。
- 数组长度确定且不可变。
public class ArrayDemo02 { public static void main(String[] args) { int[] arrays = {1,2,3,4,5}; // for (int i = 0; i < arrays.length; i++) {//普通for循环 // System.out.print(arrays[i]+" "); printArray(arrays); } public static void printArray(int[] arrays){ for (int array: arrays) {//增强型的for循环,就很好看 System.out.print(array+" "); } } }
完成反转数组代码如下:
public class ArrayDemo02 { public static void main(String[] args) { int[] arrays = {1,2,3,4,5}; // for (int i = 0; i < arrays.length; i++) {//普通for循环 // System.out.print(arrays[i]+" "); printArray(arrays); arrays = reverse(arrays); System.out.println(); printArray(arrays); } public static void printArray(int[] arrays){//打印数组 for (int array: arrays) { System.out.print(array+" "); } } public static int[] reverse(int[] arrays){//逆转数组,我这个优秀,原地地逆转空间复杂度O(n) int tmp; for (int i = 0; i < arrays.length/2; i++) { tmp = arrays[i]; arrays[i] = arrays[arrays.length-1-i]; arrays[arrays.length-1-i] = tmp; } return arrays; } }多维数组
其实原理也类似于一维数组,其中array[i]不是元素,而是一个一维数组,套娃。
public class ArrayDemo03 { public static void main(String[] args) { int[][] array = {{1,2},{2,3},{4,5},{5,6}};//静态初始化 printArray(array); } 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]+" "); } System.out.println(); } } }Arrays类
是一个数组的工具类,可以自己查看JDK帮助文档。
下载链接:JDK文档
Arrays类的方法都是static,可以直接用类名,而不用使用对象调用。(不是不能,是不用)
常用fill、sort、equals、binarySearch二分查找。
public class ArraysDemo01 { public static void main(String[] args) { int[] array = {1,2,3,89,6}; Arrays.sort(array);//升序排序 System.out.println(Arrays.toString(array));//转换为String int x = Arrays.binarySearch(array,6);//二分查找,所以必须要先排序 System.out.println(x); Arrays.fill(array,0); System.out.println(Arrays.toString(array));//转换为String } }冒泡排序
一共有八大排序,如快排、冒泡、希尔、堆、分组等吧。
自己凭直接写冒泡
结果是对的,但是不属于冒泡了都,思路如下:
外层循环length次,将下标为零的数与后面都进行擂台对决,就可以最小的放到第零,然后就是下标为1与之后的数进行比较。
每次都能固定好第i个的。
public static void mySort(int [] array){ int temp; for (int i = 0; i < array.length; i++) { for (int j = i+1; j < array.length ; j++) { if(array[i]>array[j]) { temp = array[j]; array[j] = array[i]; array[i] = temp; } } } }
而冒泡排序的要求为:
- 比较相邻的两个元素,如果第一个数比第二个大,交换位置
再写一个试试:
这个就对了,这就是相邻冒泡的排序
public static void maoPaoSort(int[] array){//时间复杂度O(n^2) int temp; for (int i = 0; i < array.length-1; i++) { for (int j = 0; j < array.length-1-i; j++) { if (array[j]>array[j+1]) { temp = array[j + 1]; array[j + 1] = array[j]; array[j] = temp; } } } }
还能优化一下,冒泡排序在即是排序好的情况下也会进行循环比较,所以只要本次没有发生交换即每两个都已经保持有序,那么排序就是已经完成的,所以咱们插个旗,如果本次没有交换,就结束了。
public static void maoPaoSort(int[] array){ int temp; boolean flag; for (int i = 0; i < array.length-1; i++) { flag = true; for (int j = 0; j < array.length-1-i; j++) { if (array[j]>array[j+1]) { temp = array[j + 1]; array[j + 1] = array[j]; array[j] = temp; flag = false; } } if (flag) {//没交换就还是true break; } } }
这里突然有了点问题,既然java是值传递,为什么这里是数组,我只是进行了形参修改,为什么能影响到实参了?这不就成了引用修改了?而且例如传值的时候比如下面的代码,结果却是形参改变,但是不会影响实参,为什么会这样?
int test=0; System.out.println("之前"+test); test(test); System.out.println("之后"+test); public static void test(int x){ x = x+1; System.out.println("val in fun"+x); } //之前0 //val in fun1 //之后0
暂且不能理解。(涉及到引用类型和对象)暂且先放放
关于java的值传递和引用传递文章
稀疏数组稀疏数组的处理方式:
-
记录数组的行数和列数,和多少个不同值
-
然后保存不同值的坐标和值
可采用n行三列的数组保存。编写的代码如下:
public class ArrayDemo06 { public static void main(String[] args) { //创建一个二维数组 11*11 1:黑 2:白 int[][] array = new int[11][11]; array[1][2] = 1; array[2][3] = 2; printArray(array);//自己写的打印二维数组 //创建压缩数组 结构:行坐标 列坐标 值 (坐标从0开始) //需要给定有几个值,否则直接121行,白压缩 int num = getNum(array); int[][] compressArray; compressArray = compress(array, num); printArray(compressArray); //再给个二维数组来存解压数组 int[][] disCompressArray; disCompressArray = disCompress(compressArray); printArray(disCompressArray); } public static int[][] compress(int[][] array,int num){//压缩 int[][] compressArray = new int[num][3]; int k = 0; for (int i = 0; i < array.length; i++) { for (int j = 0; j < array[i].length; j++) { if (array[i][j] == 1 || array[i][j] == 2) { compressArray[k][0] = i; compressArray[k][1] = j; compressArray[k][2] = array[i][j]; k++; } } } return compressArray; } public static int[][] disCompress(int[][] compressArray){//解压 int[][] disCompressArray = new int[11][11]; for (int i = 0; i < compressArray.length; i++) { for (int j = 0; j < compressArray[i].length; j++) { disCompressArray[compressArray[i][0]][compressArray[i][1]] = compressArray[i][2]; } } return disCompressArray; } public static void printArray(int[][] compressArray){//打印 for (int i = 0; i < compressArray.length; i++) { System.out.println(Arrays.toString(compressArray[i])); } } public static int getNum(int[][] array){//获取num不同值的个数 int num = 0; for (int i = 0; i < array.length; i++) { for (int j = 0; j < array[i].length; j++) { if (array[i][j]!=0) { num++; } } } return num; } }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)