Java-数组-面向对象
数组的应用练习:
数组的复制:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/* 数组的复制:重点考察是否需要返回值 int[] arr = {1,2,3}; 思路: 1.创建一个和原数组一样大小的数组 2.遍历原数组,将每个元素依次赋值给新数组的每个元素 == 比较运算符: 基本数据类型:比较的就是数值 int a = 10;int b = 20; a == b 引用数据类型:比较的是内存地址值 int[] arr = {}; int[] arr2 = {}; arr == arr2 */ public class CopyArrayDemo{ public static void main(String[] args){ int[] src = {1,2,3}; int[] copy = copyArray(src); //打印源数组 print(src); print(copy); //为了验证两个数组变量确实是不同的内存地址值,可以比较 //由于是引用数据类型,== 比较的是它们引用的地址值. System.out.println(src == copy); } public static int[] copyArray(int[] src){ //根据原数组的长度,创建一个新数组 int len = src.length; int[] dest = new int[len]; //遍历并赋值 for(int i = 0;i<len;i++){ dest[i] = src[i]; } return dest; } public static void print(int[] arr){ for(int i = 0;i<arr.length;i++){ System.out.print(arr[i] + " "); } System.out.println(); } }
数组的合并:
分析:
创建新数组,长度是两个驻足的长度之和
遍历第一个数组,依次赋值给目标数组
遍历第二个数组,依次赋值给目标数组(代码查看)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/* 合并两个数组 data1 = [1,2,3] data2 = [4,5,6] 思路: 1.创建一个大的数组:其长度是两个小数组长度之和. 2.遍历小数组,依次赋值给大数组的元素 */ public class CombineArray{ public static void main(String[] args){ int[] arr1 = {1,2,3}; int[] arr2 = {4,5,6}; //调用方法,合并两个数组 print(arr1); print(arr2); int[] dest = combine(arr1,arr2); print(dest); } public static int[] combine(int[] arr1,int[] arr2){ //创建一个大数组,长度是两个参数数组的长度之和 int[] dest = new int[arr1.length + arr2.length]; //遍历第一个数组 for(int i = 0;i<arr1.length;i++){ dest[i] = arr1[i]; } //遍历第二个数组 for(int i = 0;i<arr2.length;i++){ dest[arr1.length + i] = arr2[i]; } return dest; /* //用一个变量记录目标数组的赋值的位置 int index = 0; //创建一个大数组,长度是两个参数数组的长度之和 int[] dest = new int[arr1.length + arr2.length]; //遍历第一个数组 for(int i = 0;i<arr1.length;i++){ dest[index] = arr1[i]; index++; } //遍历第二个数组 for(int i = 0;i<arr2.length;i++){ dest[index] = arr2[i]; index++; } return dest; */ /* //用一个变量记录目标数组的赋值的位置 int index = 0; //创建一个大数组,长度是两个参数数组的长度之和 int[] dest = new int[arr1.length + arr2.length]; //遍历第一个数组 for(int i = 0;i<arr1.length;i++){ dest[index++] = arr1[i]; // index++; } //遍历第二个数组 for(int i = 0;i<arr2.length;i++){ dest[index++] = arr2[i]; // index++; } return dest; */ } public static void print(int[] arr){ for(int i = 0;i<arr.length;i++){ System.out.print(arr[i] + " "); } System.out.println(); } }
还有奇偶数索引元素的抽取,数组逆序等问题.(代码查看)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/* 抽取奇数索引的元素(偶数的自己练习) 分析: 1.得到原始数组中奇数索引的个数, 2.根据奇数索引的个数创建目标数组 3.遍历原始数组,把奇数索引的元素赋值给目标数组 推算奇数索引个数的过程: 1 0 11 1 111 1 1111 2 11111 2 ... */ public class GetOddIndexElementDemo{ public static void main(String[] args){ int[] src = {1,5,2,7,8,5,6}; print(src); int[] dest = getOddIndex(src); print(dest); } //打印数组元素 public static void print(int[] arr){ for(int i = 0;i<arr.length;i++){ System.out.print(arr[i] + " "); } System.out.println(); } //定义方法,抽取原始数组的奇数索引的元素值. public static int[] getOddIndex(int[] src){ //1.得到原始数组中奇数索引的个数 int len = src.length / 2; //2.根据奇数索引的个数创建目标数组 int[] dest = new int[len]; // int index = 0; // for(int i = 0;i<src.length;i++){ if(i % 2 != 0){ dest[index++] = src[i]; } } return dest; } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/* 数组的逆序: 两两交换!! 次数问题: 元素的个数 / 2 交换两个变量的值的操作是重复执行的动作. */ public class ReverseArrayDemo{ public static void main(String[] args){ int[] arr = {1,2,3,4,5}; System.out.println("逆序之前:"); print(arr); reverse(arr); System.out.println("逆序之后:"); print(arr); } public static void print(int[] arr){ for(int i = 0;i<arr.length;i++){ System.out.print(arr[i] + " "); } System.out.println(); } //自定义方法,实现数组的逆序: //返回值类型:void //形参列表:int[] public static void reverse(int[] arr){ //计算出两两交换的次数 int count = arr.length / 2; // for(int i = 0;i<count;i++){ //交换两个变量的值 int tmp = arr[i]; arr[i] = arr[arr.length - 1 - i]; arr[arr.length - 1 - i] = tmp; } } }
Java中参数传递的原则:
Java中所有的参数传递原则是:值传递
不论是基本数据类型还是引用数据类型,传递给形参的都是实参的副本!
基本数据类型的形参,在方法体内的更改,在方法外看不到.
应用数据类型的形参,在方法体内对应用内存地址中的元素的更改,在方法外可以看到.
(代码中详细介绍)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/* 参数传递的原则: 若参数是基本数据类型:传递是实参的一个副本. 方法体内对形参数据的更改,在方法外看不到 若参数是引用数据类型:传递是实参的一个副本. 方法体内对形参指向的对象的数据的更改,在方法外可以看到!!! */ public class PassArgsDemo{ public static void main(String[] args){ /* // int x = 10; int y = 20; clear(x,y); System.out.println(x +","+ y);//10,20 */ // int[] arr = {1,2,3}; // print(arr); //单独调用 clear(arr); //查看数组的元素值 print(arr); } public static void print(int[] arr){ for(int i = 0;i<arr.length;i++){ System.out.print(arr[i] + " "); } System.out.println(); } //自定义方法,参数是基本数据类型 public static void clear(int a,int b){//形参上的a,b实际上只是接收了实参的值的副本!! System.out.println("clear方法被调用"); //把传递进来的参数设置为0 a = 0; b = 0; } //自定义方法,参数是引用数据类型 public static void clear(int[] arr){ //遍历数组,都赋值为0 for(int i = 0;i<arr.length;i++){ arr[i] = 0; } } } 值传递: 不论是基本数据类型还是引用数据类型,传递给形参的都是实参的副本!! 只不过: 基本数据类型的形参,在方法体内的更改,在方法外不看到. 引用数据类型的形参,在方法体内的更改,在方法外可以看到. public static void test1(int a){ //这里对形参a做的所有改变,都是对副本的改变,在方法外部是看不到的!!! } public static void test2(int[] arr){ //这里对arr指向的内存空间的更改,在方法外可以看到, //因为两个引用都指向的是同样的内存空间 //但是对arr重新赋值,在方法外是看不到的. arr = null; //表示把形参引用的地址值改了,并不是把arr原来指向的内存地址的内容改了. //此时在方法外是看不到改变的. }
二维数组:
元素本身是一维数组的一维数组.
初始化方式:
动态初始化:
int[][] arr = new int[3][];
int[][] arr = new int[3][2];
静态初始化:
int[][] arr = new int[][]{{1},{2,3},{4,5,6}};
int[][] arr = {{7},{8,9},{10,11,12}};
二维数组的应用(查看代码):
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/* 二维数组:元素本身是一维数组的 一维数组. int[][] arr = new int[3][]; //定义一个有三个元素的二维数组,它的每个元素又是另一个一维数组 arr[0] = new int[2]; arr[1] = {1,2,3}; 二维数组的遍历: 关键是第二维数组的长度的确定. 二维数组名[index].length */ public class Dem2Array{ public static void main(String[] args){ /* //定义一个二维数组,动态初始化,指定长度是3 int[][] arr = new int[3][]; //指定每个元素指向的一维数组是... arr[0] = new int[2]; arr[1] = new int[3]; //打印二维数组的各个元素值: System.out.println(arr[0]); System.out.println(arr[1]); System.out.println(arr[2]); //访问二维数组中的元素 System.out.println(arr[0][0]);//0 //第二种格式:二维数组的每个元素指向的一维数组长度是一致的. int[][] arr2 = new int[2][4]; //第三种格式:静态初始化,指定值,不指定长度! int[][] arr3 = new int[][]{{1},{2,3,4,5,6},{1,2}}; */ int[][] arr3 = new int[][]{{1},{2,3,4,5,6},{1,2}}; //遍历二维数组 //外层循环控制的是二维数组的元素的遍历 for(int i = 0;i<arr3.length;i++){ //内层循环控制的是最里层的一维数组的元素的遍历 for(int j = 0;j<arr3[i].length;j++){ System.out.print(arr3[i][j] + " "); } System.out.println(); } } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/* 获取二维数组所有元素的个数: 计数器思想: 定义一个变量,初始值必须为0,满足条件时,加1. */ public class GetCountDemo{ public static void main(String[] args){ int[][] arr = {{1},{2,3},{4,5,6},null}; arr[3] = new int[]{7,8,9};//在二维数组动态初始化时,一维数组的初始化,不能简写!!! // int count = 0; for(int i = 0;i<arr.length;i++){ for(int j = 0;j<arr[i].length;j++){ count++; } } // System.out.println("二维数组的元素个数是: " + count); } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/* 假设以下是某公司四个季度的销售记录,将数据保存在一个二维数组中,并统计全年的销量之和 第一季度:10,20,30 第二季度:40,50,60 第三季度:70,80,90 第四季度:30,30,30 */ public class GetSum{ public static void main(String[] args){ int[][] arr = {{10,20,30},{40,50,60},{70,80,90},{30,30,30}}; 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); } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/* 杨辉三角形: 1 11 121 1331 ... 规律: 每行的数字个数和行数相同! 行首和行尾都为1, 其它的数字:是它正上方的数字和紧邻的前一个数字之和. */ public class YangHuiDemo{ public static void main(String[] args){ int[][] arr = new int[8][]; //给每个二维数租的元素赋值 for(int i = 0;i<arr.length;i++){ //创建一个新的数组 arr[i] = new int[i+1]; //循环新建的一维数组 for(int j = 0;j<arr[i].length;j++){ //对新建的一维数组赋值 if(i == 0 || j == 0 || j == i){ arr[i][j] = 1; }else{ arr[i][j] = arr[i-1][j] + arr[i-1][j-1]; } } } 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(); } } }
面向对象编程:
类和对象的关系:
定义一个Dog类: 成员变量: String color; int price; String name; int age; 成员方法: public void eat(){ } public void sleep(){ } 类是一个抽象的概念: 作用主要是用来创建对象!!! 创建对象的格式: 类名 对象名 = new 类名(); Dog d = new Dog(); */
定义类,使用类:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/* 定义一个Dog类: 成员变量: String color; int price; String name; int age; 成员方法: public void eat(){ } public void sleep(){ } 类是一个抽象的概念: 作用主要是用来创建对象!!! 创建对象的格式: 类名 对象名 = new 类名(); Dog d = new Dog(); */ public class Dog{//成员变量(属性),如果定义时没有赋值,成员变量都有默认值:null,0 String name; // null int age = 2; // 2 String color; // null //成员方法:和之前定义方法的格式一致,把static去掉!!! public void eat(){ System.out.println("eat"); } public void run(){ System.out.println("run"); } } /* //可以在自定义类中写main方法测试,但是不好! public static void main(String[] args){ //使用之前定义Dog类创建对象: Dog d = new Dog(); //调用对象的方法 d.eat(); d.run(); //访问对象的属性 System.out.println(d.name); System.out.println(d.age); System.out.println(d.color); } */
/* Dog类的测试类 */ public class DogDemo{ public static void main(String[] args){ Dog d = new Dog(); d.eat(); d.run(); System.out.println(d.name); System.out.println(d.age); System.out.println(d.color); } } /* 程序在编译时,会自动检测源文件中使用到的类,如果这个类是我们自定义的类,并且没有经过编译的话,那么系统就会自动的把程序中使用到的类进行编译.这样在程序运行时,就不会出现找不到类的错误. */
创建对象:
访问对象的变量:
调用对象的方法: