1、二维数组
1、二维数组的动态初始化
package org.westos.demo;
public class ArrayDemo {
public static void main(String[] args) {
//二维数组
/*
二维数组的元素是一维数组,一维数组的元素是基本类型和引用类型。
*/
//动态初始化二维数组:由我们定义长度,由系统赋予默认值
//数据类型[][] 数组名 = new 数据类型[必选/二维数组长度][可选/一维数组长度];
int[][] array = new int[2][2];
}
}
package org.westos.demo;
public class ArrayDemo2 {
public static void main(String[] args) {
int[][] arr = new int[2][3];
//2:必须写,代表二维数组的长度,即有多少行一维数组
//3:可选可不选,代表一维数组的长度,写与不写是有区别的
//取二维数组的元素,元素为一维数组
int[] arr0 = arr[0];
System.out.println(arr0);
//[I@1b6d3586
int[] arr1 = arr[1];
System.out.println(arr1);
//[I@4554617c
//取一维数组中存的值
int arr0_one = arr[0][0];
System.out.println(arr0_one);
//0
int arr0_two = arr[0][1];
System.out.println(arr0_two);
//0
int arr0_three = arr[0][2];
System.out.println(arr0_three);
//0
//给一维数组中的元素赋值
arr[0][0] = 10;
arr[0][1] = 20;
arr[0][2] = 30;
System.out.println(arr[0][0]);
//10
System.out.println(arr[0][1]);
//20
System.out.println(arr[0][2]);
//30
}
}
当第二个中括号不选时:
package org.westos.demo;
public class ArrayDemo3 {
public static void main(String[] args) {
//第二个[]不选的情况:
int[][] arr = new int[2][];
//初始化了二维数组,每一个一维数组的默认值为null(数组是引用类型,引用类型的默认值为null)
int[] arr0 = arr[0];
System.out.println(arr0);
//null
}
}
内存图:

当第二个中括号选上时:
package org.westos.demo;
public class ArrayDemo4 {
public static void main(String[] args) {
//第二个[]选的情况:
int[][] arr = new int[2][2];
System.out.println(arr[0]);
//[I@1b6d3586
System.out.println(arr[1]);
//[I@4554617c
//初始化二维数组,元素默认值为null,初始化每个一维数组,元素默认值为0
}
}
内存图:

二维数组的元素存放的是各个一维数组的地址值,引用。
手动初始化一维数组
package org.westos.demo;
public class ArrayDemo5 {
public static void main(String[] args) {
int[][] arr = new int[2][];
//null,null
//手动初始化一维数组
arr[0] = new int[2];
arr[1] = new int[3];
System.out.println(arr[0]);
//[I@1b6d3586
System.out.println(arr[1]);
//[I@4554617c
System.out.println(arr[0][0]);
System.out.println(arr[0][1]);
System.out.println(arr[1][0]);
System.out.println(arr[1][1]);
System.out.println(arr[1][2]);
//一维数组元素默认值为0
}
}
二维数组的每个一维数组长度可以不一致。
以下格式也可以表示二维数组
a:数据类型 数组名[][] = new 数据类型[m][n];
b:数据类型[] 数组名[] = new 数据类型[m][n];
这两种格式不推荐使用
注意下面定义的区别
int x,y;
x,y都是int类型;
int[] x,y[];
区别是:
int[] x,y[];//定义了两个数组 一个是一维数组x 一个是二维数组y
x=new int[3];
y=new int[3][];
y[0] = x
2、二维数组的静态初始化
package org.westos.demo2;
public class ArrayDemo {
public static void main(String[] args) {
//二维数组的静态初始化:由我们给元素赋值,由系统计算长度
int[][] arr = new int[][]{{10, 20}, {30, 40, 50}, {60}};
System.out.println(arr.length);
//3
System.out.println(arr[0][0]);
//10
System.out.println(arr[0][1]);
//20
System.out.println(arr[2][0]);
//60
System.out.println(arr[arr.length-1][arr[arr.length-1].length-1]);
//60
//简化版
double[][] array = {{1.0, 2.0}, {3.0f, 4}};
}
}
3、例题
1、二维数组的遍历
package org.westos.demo3;
public class ArrayDemo {
public static void main(String[] args) {
//二维数组的遍历
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] + "\t");
}
System.out.print("\n");
}
}
}
2、二维数组求和
package org.westos.demo3;
public class ArrayDemo2 {
public static void main(String[] args) {
//二维数组的求和
int[][] arr = {{22,66,44}, {77,33,88}, {25,45,65}, {11,66,99}};
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);
//四个季度的营业额为641
}
}
3、杨辉三角
package org.westos.demo3;
import java.util.Scanner;
public class ArrayDemo3 {
public static void main(String[] args) {
//杨辉三角
Scanner sc = new Scanner(System.in);
System.out.println("请输入杨辉三角的行数:");
int n = sc.nextInt();
int[][] arr = new int[n][];
for (int i = 0; i < arr.length; i++) {
arr[i] = new int[i + 1];
arr[i][0] = arr[i][i] = 1;
if (i > 1) {
for (int j = 1; j < i; 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 < arr[i].length; j++) {
System.out.print(arr[i][j] + "\t");
}
System.out.print("\n");
}
}
}
4、Java中的参数传递问题
package org.westos.test;
public class MyDemo {
public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println("a: " + a + ",b: " + b);
//a: 10,b: 20
change(a,b);
System.out.println("a: " + a + ",b: " + b);
//a: 10,b: 20
int[] arr = {1,2,3,4,5};
change(arr);
System.out.println(arr[1]);
//4
}
private static void change(int a, int b) {
System.out.println("a: " + a + ",b: " + b);
//a: 10,b: 20
a = b;
//a=20
b = a + b;
//b=40
System.out.println("a: " + a + ",b: " + b);
//a: 20,b: 40
}
private static void change(int[] arr){
for(int x = 0 ; x < arr.length ; x++){
if(arr[x]%2 == 0){
//如果数组元素是偶数,乘以二
arr[x] *= 2;
}
}
//arr = {1,4,3,8,5}
}
}
参数的传递问题:
基本类型作为参数传递,属于值传递,会把这个变量的值传过去;
引用类型作为参数传递,属于引用传递,传递的是地址值;
基本类型作为参数传递,形参的改变不会影响实参;
引用类型作为参数传递,形参的改变会影响实参。
2、递归
在方法的定义中调用方法本身的现象。
注意事项:
递归要有出口;(if n == ?) return x;不然会造成栈溢出
递归次数不宜过多,过多也会有栈溢出的可能;
java.lang.StackOverFlowError
求5的阶乘。
递归实现
package org.westos.demo;
public class DiguiDemo {
public static void main(String[] args) {
//5! = 5 * 4 * 3 * 2 * 1 = 120
int num = 5;
int result = method(num);
System.out.println("5的阶乘为" + result);
//5的阶乘为120
}
public static int method(int i) {
if (i == 1) {
return 1;
}
return i * method(i - 1);
}
}
递归体现的是拆分合并的思想。

循环实现
package org.westos.demo;
public class DiguiDemo2 {
public static void main(String[] args) {
//使用循环计算5!
int num = 5;
int result = 1;
for (int i = num; i > 0; i--) {
result *= i;
}
System.out.println("5的阶乘为" + result);
//5的阶乘为120
}
}
斐波那契数列
从第三个数开始,等于前两个数之和。
非递归做法:
package org.westos.demo;
public class FiboTest {
public static void main(String[] args) {
int[] arr = new int[12];
arr[0] = arr[1] = 1;
for (int i = 2; i < arr.length; i++) {
arr[i] = arr[i-1] + arr[i-2];
}
System.out.println("12个月后的兔子个数为" + arr[arr.length-1]);
//12个月后的兔子个数为144
}
}
递归做法:
package org.westos.demo;
public class FiboDemo {
public static void main(String[] args) {
int num = 12;
int result = method(num);
System.out.println("12个月后的兔子个数为" + result);
//12个月后的兔子个数为144
}
public static int method(int n) {
if (n == 1 || n == 2) {
return 1;
}
return method(n - 1) + method(n - 2);
}
}
空间优化:
package org.westos.demo;
public class FiboTest2 {
public static void main(String[] args) {
int a, b;
a = b = 1;
for (int i = 3; i <= 12; i++) {
int temp = b;
b = a + b;
a = temp;
}
System.out.println("12个月后的兔子数量为" + b);
//12个月后的兔子数量为144
}
}
3、面向对象
1、面向对象概述
面向对象:基于面向过程,把这些过程封装起来,去调用。
面向对象,将我们的角色从之前的执行者变为了指挥者,需要用到某个功能时,调用某个类即可。
面向对象的三大特征:
封装
继承
多态
类和对象的概念:
类:抽象的,是一组具有相同属性和行为的集合;
对象:具体的,是该类事物的具体体现。
如何定义一个类:使用关键字class。
定义一个Person类:
package org.westos.demo;
//使用关键字class定义一个类
public class Person {
//事物--------对应Java中-------类
//属性------------------------成员变量
//功能------------------------成员方法
//定义成员变量,在方法外
String name = "张三";
int age = 22;
char gender = '男';
//定义成员方法
public void sleep() {
System.out.println("睡觉");
}
public void eat() {
System.out.println("吃饭");
}
public void playGame(String game) {
System.out.println("玩" + game);
}
}
package org.westos.demo;
public class PersonTest {
public static void main(String[] args) {
//在测试类中使用定义的Person类的属性和功能
//类是一个抽象的概念,不能直接使用,要使用,我们必须完成对类的实例化
//所谓实例化,就是创建该类对象
//如果创建该类的对象,使用关键字new来完成
//类名 对象名 = new 类名();
Person person = new Person();
//对象才是一个类的具体表现,有了该类的对象后,就可以使用对象来调用类的属性和功能
//当然,一个类可以创建它的很多对象
String name = person.name;
int age = person.age;
char gender = person.gender;
System.out.println("name = " + name + ", age = " + age + ", gender = " + gender);
//name = 张三, age = 22, gender = 男
person.eat();
//吃饭
person.sleep();
//睡觉
person.playGame("LOL");
//玩LOL
System.out.println("============================");
Person person1 = new Person();
//再创建一个Person类的对象
person1.name = "李四";
person1.age = 30;
person1.gender = '女';
//重新设置属性的值
System.out.println(person1.name);
//李四
System.out.println(person1.age);
//30
System.out.println(person1.gender);
//女
}
}
定义一个手机类
package org.westos.demo;
/**
* 手机类:
* 成员变量:品牌、价格、颜色
* 成员方法:打电话、发短信
*/
public class Phone {
String brand;
double price;
String color;
public void call(String name) {
System.out.println("给" + name + "打电话");
}
public void sendMessage(String name, String content) {
System.out.println("给" + name + "发短信,内容是" + content);
}
}
package org.westos.demo;
public class PhoneTest {
public static void main(String[] args) {
Phone phone = new Phone();
//创建对象
String brand = phone.brand;
double price = phone.price;
String color = phone.color;
//输出成员变量的值
System.out.println("品牌:" + brand + ", 价格:" + price + ", 颜色:" + color);
//品牌:null, 价格:0.0, 颜色:null
//给成员变量赋值
phone.brand = "小米";
phone.price = 4999.0;
phone.color = "深空灰";
System.out.println("品牌:" + phone.brand + ", 价格:" + phone.price + ", 颜色:" + phone.color);
//品牌:小米, 价格:4999.0, 颜色:深空灰
//调用成员方法
phone.call("Tom");
//给Tom打电话
phone.sendMessage("Candy", "下午两点见");
//给Candy发短信,内容是下午两点见
}
}
2、对象的内存图
一个对象的内存图

两个对象的内存图

三个对象的内存图
