数组
1、java中的数组:是一个用来存储数据的容器
/*
* **所有声明的变量存放于栈(stack)区:系统自动分配,不用我们控制
*
* 数组的声明:
* int[] array; (*)
* int array[] ;
* 数值是引用数据类型:数据存在在堆heap区:
*
* 数组的初始化:
* 数组数据类型[] 变量名=new 数组数据类型[数组长度]
* 数组中的数据存放在堆heap区,堆heap区的内存需要程序员区控制,使用内存空间分配符new开辟内存
*
*/
//声明
int[] array;
int array_new[];
//初始化
array=new int[5];
System.out.println();
//动态初始化
array=new int[5];//堆内存中创建了一个数据对象(开一个房间),存放5个元素的数组
System.out.println(array);//[I@7852e922
//控制台输出数组内容
System.out.println(Arrays.toString(array));//[0, 0, 0, 0, 0]
//定义
char[] char_array=new char[5];
System.out.println(Arrays.toString(char_array));//[ , , , , ]
//定义一个引用数据类型的数组
String[] strign_array=new String[5];
System.out.println(Arrays.toString(strign_array));//[null, null, null, null, null]
//静态初始化
/**数组初始化时 赋值自己想要的值*/
int[] array_int=new int[] {1,2,3,4,5,6};
int[] array_int_two= {12,13,14,15,16,17};//.class --自动加上new
//数组的赋值 索引从0开始
array[0]=13;
array[1]=14;
array[2]=15;
array[3]=16;
array[4]=17;
System.out.println(Arrays.toString(array));
/*array[5]=18;//java.lang.ArrayIndexOutOfBoundsException: 5 数组越界异常
*/ /*array[4]="zhangsan"; array是int类型的数组,元素只能是int类型*/
//数组的访问:Arrays.toString(数组名)
/**通过索引访问*/
System.out.println(array[3]);//16
/**数组的快速访问*/
for(int i=0;i<array.length;i++) {
System.out.println(array[i]);
}
/**foreach循环 加强for循环
* for(数组元素数据类型 变量名:遍历的数组名) {
}
该循环方式为按照数组下标顺序
,依次将冒号右边数组中的每个元素赋值给冒号左边的变量,数组长度为for循环的次数。
* */
for(int j:array) {
System.out.println("j:"+j);
}
/*
int a;
a=10;
System.out.println(a);*/
}
二维数组
/**
*[数组,数组,数组..]
*二维数组:Java中没有真正的多维数组,只有数组的数组
*
*声明:
*数据类型[][] 数组名 ;
*数据类型 数组名[][];
*数据类型[] 数组名[];
*
* 创建:
* int[][] arrays_4=new int[3][3];
int[][] arrays_5=new int[3][];
*
* 初始化:
* 数组类型 数组名[ ][ ] = {{元素11,元素12,…} , {元素21,元素22,… }}
* 数组类型 数组名[ ][ ] = new 数据类型[ ][ ] { {元素11,元素12,…} , {元素21,… } }
*
*/
//声明
int[][] arrays_1;
int arrays_2[][];
int[] arrray_3[];
//创建二维数组 定义
int[][] arrays_4=new int[3][3];
int[][] arrays_5=new int[3][];
/*int[][] arrays_6=new int[][];//维度必须初始化,告诉编译器数组有多少个元素*/
/*int[][] arrays_6=new int[][3];//维度必须初始化empty dimension*/
/*int[] array_1=new int[5];*/
//二维数组的初始化
int[][] arrays_6=new int[][]{{1,2,3},{4,5},{6,7}};
int[][] arrays_7={{1,2,3},{4,5},{6,7}};
System.out.println(arrays_6);//[[I@7852e922
System.out.println(arrays_7);//[[I@4e25154f
//二维数组的访问
System.out.println(Arrays.toString(arrays_6));
System.out.println(Arrays.toString(arrays_6[0]));//[1, 2, 3]
System.out.println(Arrays.toString(arrays_6[4]));//数组越界
//遍历二维数组
//遍历二维数组
/*System.out.println(arrays_6.length);//3 行数*/
/*for(int i=0;i<arrays_6.length;i++) {
//行数
System.out.println(Arrays.toString(arrays_6[i]));
//每行每列的结果
for(int j=0;j<arrays_6[i].length;j++) {
System.out.println(arrays_6[i][j]);
}
}*/
/*foreach*/
for(int[] i:arrays_6) {
for(int j:i) {
System.out.println(j);
}
}
//二维数组的赋值
int[][] arrays_8=new int[4][4];
arrays_8[0][0]=1;
arrays_8[0][1]=1;
arrays_8[0][2]=1;
arrays_8[0][3]=1;
arrays_8[1][0]=1;
arrays_8[1][1]=1;
arrays_8[1][2]=1;
arrays_8[1][3]=1;
/**
* 快速赋值:
* 1 2 3
* 4 5 6
* 7 8 9
*/
int num=1;
int[][] arrays_9=new int[3][3];
for(int i=0;i<arrays_9.length;i++) {
//给每一行每一列赋值
for(int j=0;j<arrays_9[i].length;j++) {
arrays_9[i][j]=num;
num++;
}
}
冒泡排序:
/**
* 冒泡排序:
*
*
* {78,12,23,6,17,49}
*
*
*/
int[] a= {78,12,23,6,17,49};
//升序排序
/*for(int i=0;i<a.length-1;i++) {
if(a[i]>a[i+1]) {
int temp=a[i+1];
a[i+1]=a[i];
a[i]=temp;
}
}
System.out.println(Arrays.toString(a));//[12, 23, 6, 17, 49, 78]
*/
//降序排序
for(int j=0;j<a.length;j++) { //循环六次
for(int i=0;i<a.length-1;i++) {//6个数比较5次
if(a[i]>a[i+1]) {
int temp=a[i+1];
a[i+1]=a[i];
a[i]=temp;
}
}
System.out.println(Arrays.toString(a));
}
/*System.out.println(Arrays.toString(a));
for(int j=0;j<a.length;j++) { //循环六次
for(int i=0;i<a.length-1;i++) {//6个数比较5次
if(a[i]<a[i+1]) {
int temp=a[i+1];
a[i+1]=a[i];
a[i]=temp;
}
}
}
System.out.println(Arrays.toString(a));*/
//优化冒泡排序
for(int j=1;j<a.length;j++) { //循环五次
for(int i=0;i<a.length-j;i++) {//6个数比较5次
if(a[i]>a[i+1]) {
int temp=a[i+1];
a[i+1]=a[i];
a[i]=temp;
}
}
}
System.out.println(Arrays.toString(a));
}
方法的定义和调用
- 方法的定义
/***
* 方法是什么?
* 方法是完成某个功能的一组语句,通常将常用的功能写成一个方法
* 方法使用大括号包含语句块称为方法体,用于执行特定的功能操作
*
* 方法的分类:
* 无参无返回值
* 无参有返回值
*
* 有参无返回值
* 有参有返回值
*
* 方法的定义:
* 方法定义在类中
* 方法不能定义在方法中
*
* 作用:可以实现代码的重用。简化了程序的编写和维护工作。
*/
public class _方法的说明_方法的分类和定义 {
//无参无返回值
/**
* public:访问修饰符
* void:标志着这个方法没有返回值
* startXiJi:方法名
*/
public void startXiJi() {
//实现洗衣机工作的方法 --在控制台中输出
System.out.println("我是无参无返回值方法--洗衣机工作");
}
//无参有返回值
/**
*
* public:访问修饰符
* int:标志着这个方法返回值是int类型
* return:这个方法返回的值
* 注意:return的值的数据类型一定要和方法返回值类型一致
* 有返回值的方法必须要有return(无论如何都要执行return),而且一个方法只能返回一个值
* @return
* retrun是一个方法结束的标志,一旦return执行之后,return之后的代码就没有意义了
*/
public int getAge() {
int age=5;
if(age>10) {
return age;
}else {
return age;
/*System.out.println(" ss");*/
}
/*return 20;*/
}
//有参无返回值
/**
* int money:形式参数--这个方法执行需要什么类型的数据,就要给什么数据类型的
*
*
* @param money
*/
public void startBingXiang(int money) {
System.out.println("有参无返回值");
}
public void getName(int userId,String phone) {
System.out.println("有参无返回值");
}
//有参有返回值
/**
* 方法的返回值可以是基本数据类型也可以是引用数据类型
*
*
*/
public int[] getSex(int id) {
int[] arrays=new int[5];
return arrays;
}
/**
* main:程序的入口
* @param args
*/
public static void main(String[] args) {
}
- 方法的调用
/**
* 注意:需要根据方法名称调用方法,方法只有在被调用后才生效
*
* 方法的调用:
* 定义的方法可以被多次调用。
*定义方法中的代码,只有在调用后才生效。
*
* 无参无返回值方法的调用
*
*
* @param args
*/
//无参无返回值方法
public static void startXiYiJi() {
System.out.println("无参无返回值的方法--让洗衣机启动");
}
/**
* 有参无返回值
* 形参的作用域在整个方法,
* 变量只有初始化才能使用,形参其实就是一个变量,形参的初始化是在方法被调用的时候完成的
* @param money
*/
public static void startShouMaiJi(int money) {
System.out.println("有参无返回值"+money);
}
public static void startDianShiJi(int id,String name) {
System.out.println(name+"打开了"+id+"号电视机");
}
/**
* 无参有返回值
*/
public static String getName() {
System.out.println("无参有返回值的方法");
return "lisi";
}
/**
* 有参有返回值
*/
public static String getName(String userName,String password) {
String name="zhangsan";
System.out.println("有参有返回值的方法");
return name;
}
/**
* 程序的入口
* @param args
*/
public static void main(String[] args) {
/*无参无返回值
startXiYiJi();
startXiYiJi();
startXiYiJi();
/*
* 有参无返回值
* 实参和形参的数量、类型、顺序必须匹配
* qian和300称为实参
* 实参可以是常量,也可以是有值的变量。
int qian=100;
startShouMaiJi(qian);//传参
startShouMaiJi(300);
startDianShiJi(1,"张三");
*/
/*
*无参有返回值的方法
* 如果方法有返回值,调用方法可以得到该方法的返回值,然后赋值给与方法返回值类型相同的变量
String name=getName();
if(name.equals("lisi")) {
System.out.println(name);
}else {
System.out.println("不是他");
}*/
/*有参有返回值的方法
*
String name=getName("lisi","123");
System.out.println(name);*/
}
方法的互相调用
/**
* 方法之间互相调用
*
* 发动机启动需要油,如果油量大于200Ml那么才能启动,发动机启动后车才能跑起来
*/
public static void startFaLali() {
boolean t=startFaDongJi();
if(t) {
System.out.println("思行的法拉利 跑起来了,来兜风呀");
}
}
public static boolean startFaDongJi() {
boolean temp=false;
int you=getYouLing(500);
//油量大于200发动机才能启动
if(you>200) {
temp=true;
}
return temp;
}
public static int getYouLing(int youLiang) {
int realYou=youLiang/2;
return realYou;
}
_基本数据类型和引用类型作为参数比较
/**
* 参数是基本数据类型
*
* 变量随着方法的执行完毕而死亡
*
* @param x
* @return
*/
public static void getX(int x) {
x=x*10;
/*System.out.println("方法中的x"+x);*/
}
/**
* 参数是引用数据类型
*
* 传递的是地址,拿到引用地址后可以对堆区中的对象的数据进行操作
* @param y
*/
public static void getY(int[] y) {
System.out.println(y);
y[0]=y[0]*10;
}
public static void main(String[] args) {
int x=10;
System.out.println("调用方法前x:"+x);//10
getX(x);
System.out.println("调用方法后x:"+x);//10
int[] y= {10};
System.out.println(y);
System.out.println("调用方法前y:"+y[0]);//10
getY(y);
System.out.println("调用方法后y:"+y[0]);//100
}
方法的重载
/**
* 方法的重载:方法的重载就是在同一个类中允许同时存在一个以上同名的方法
*
*
* 实现方法重载:一同一不同
* 方法名相同
*方法的参数列表不同:参数的个数或者参数的类型不同
*返回值可以同可以不同
*作用:相同名称的方法实现的功能不一样,扩展方法的功能
*/
public void getUser(String userName,String passWord) {
System.out.println("通过名字和密码查询用户");
}
//方法重载
public void getUser(String userName) {
System.out.println("通过名字查询用户");
}
//方法重载
public void getUser(int sex) {
System.out.println("通过性别查询用户");
}
方法的递归
/**
* 方法的递归:某个方法本身调用自己,达到循环执行该方法的效果
*/
//编写一个方法,求整数n的阶乘,例如5的阶乘是1*2*3*4*5
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int message=sc.nextInt();
/**
* 有返回值的方法可以直接输出
*/
System.out.println(getResult(message));
}
public static int getResult(int message) {
if(message==1) {//如果message等于1结束递归
return 1;
}
return message*getResult(message-1);//8*7*6*5*4*3*2*getResult(1)
}
面向对象基础
-
构造器
/** * * new :分配堆内存,创建对象 * 构造方法可以重载 * * 构造器(构造方法): * 语法: * <修饰符> 类名(){ * * } *构造方法名必须与类相同的名称 不含返回值类型,也没有void 不能在方法中用return语句返回一个值 * * * 作用: * 初始化对象--包括初始化属性(给默认值)以及方法 * 属性(成员变量)和方法都是初始化之后才能使用 * 成员方法可以直接调用属性 * * 执行: * 在对象被创建之前要完成对象的初始化工作,调用构造方法 * 对象创建出来的同时就完成了对象的初始化工作 * * * 注意: * * * 如果代码中没有声明构造器,编译器会自动给我加上一个无参的构造器,因为对象初始化一定要调用构造器 * * 有参构造器: * <修饰符> 类名(参数列表){ * * } * 作用: * 初始化对象,初始化属性(自定义值)以及方法 * * * 注意:一个类中有了有参的构造器,编译器会将无参的构造器删除 * (也就是说当你提供了构造器了之后,编译器不会给你加上无参构造器了) * * 所以我们一般这样操作:提供有参构造器的同时也提供无参的构造器 */ String name; int age; char sex; /** * 无参构造器 构造方法 */ public Person() { System.out.println("我是无参构造器"); } /** * 有参构造器 */ public Person(String name,int age,char sex) { System.out.println("我是有参构造器"); this.name=name; this.age=age; this.sex=sex; } public void getResult() { System.out.println("name:"+this.name+" age:"+this.age+" sex:"+this.sex); } public static void main(String[] args) { Person p1=new Person(); p1.age=10; p1.name="liss"; p1.sex='女'; p1.getResult(); /* p1.getResult();*/ /*Random r=new Random(); int a=r.nextInt(); */ Person p2=new Person("zhangsan",12,'男'); /*p2.name="zhangsan";*/ p2.getResult(); }
2、垃圾回收机制
/***
*
* 垃圾回收机制:
* 堆内存自动回收垃圾线程
*
* 垃圾:只要没有引用指向,jvm垃圾回收线程会把该对象识别为垃圾
* (我们并不知道垃圾回收线程什么时候执行,一般是堆内存的使用达到一定的容量时执行)
* 1、匿名对象
* 2、对象的引用被赋值为null
* 3、超出对象的声明周期
*
* finalize():销毁对象,内存的使用达到一定的容量时执行,垃圾回收线程开始工作,
* 去找堆内存中那些对象时垃圾,当对象被识别为垃圾就会调用该对象的finalize()方法销毁该对象
*
* @author Administrator
*
*/
public class GarbageRecycling {
public static void getX() {
int x=10;
}
public static void getY() {
int y=10;
}
public static void main(String[] args) {
/*getX();*/
GarbageRecycling gr=new GarbageRecycling();
/* GarbageRecycling gr1=new GarbageRecycling();
GarbageRecycling gr2=new GarbageRecycling();*/
//如果只想执行一次对象的操作,可以创建匿名对象
new GarbageRecycling().getX();
new GarbageRecycling().getY();
new GarbageRecycling().getX();
gr=null;
new GarbageRecycling().getY();
for(int i=0;i<10;i++) {
GarbageRecycling grl=new GarbageRecycling();
}
}
继承
/**
* 继承(泛化):public class Worker extends Employee
* 子类 is a kind of 父类
*
* 语法:子类(派生类) extends 父类(基类,超类)
* 注意:子类继承了父类,就可以使用父类非private修饰的方法和属性
* 作用:子类继承父类的所有非private修饰的属性和方法,同时也可以增加自己的属性和方法。
* 1、提高代码复用率
* 2、子类功能得到增强
*
*
* 注意:Java中只支持单继承,但是支持一个类可以是另一个类的爷爷
* 一个父类可以有多个子类
*
*
* @author Administrator
*
*/
封装
/**
* 封装:
* 就是将不想或不该告诉他人的东西隐藏起来,
* 将可以告诉他人的内容公开(隐藏对象的属性和方法的实现细节,只公开对外接口)
*
* 本类中有的一些属性或者方法不想在其他类中或者其他包中的类可见(被调用),
* 将可以对外的类公开的属性或者方法提供对外访问的方法
*
* 访问修饰符:控制类中的方法或者属性访问的权限
*
* @author Administrator
*
*/
访问修饰符
同一个类中 | 同个包中的其他类 | 不同包中的子类 | 不同包中的非子类 | |
---|---|---|---|---|
private | ok | not | not | not |
default | ok | ok | not | not |
protected | ok | ok | ok(用子类引用调用父类的protected修饰方法和属性,不能用父类的) | not |
public | ok | ok | ok | ok |
/**
* 属性
*/
private int age;
String name;
protected String address;
public int salary;
/**
* 成员方法
*/
private void getPrivate() {
System.out.println("private修饰的方法");
}
void getDefault() {
System.out.println("default修饰的方法");
}
protected void getProtected() {
System.out.println("protected修饰的方法");
}
public void getPublic() {
System.out.println("public修饰的方法");
}
public static void main(String[] args) {
TestEncapsulation_one one=new TestEncapsulation_one();
one.age=10;
one.getPrivate();
one.name="李四";
one.getDefault();
System.out.println(one.age);
}
类的修饰符只有两个:public 和default
单例模式
-
保证一个类仅有一个实例(对象),并提供一个访问它的全局访问点。
-
要点:
某个类只能有一个实例;
它必须自行创建这个实例;
必须自行向整个系统提供这个实例。 -
实现:
1、拥有一个私有构造器;
2、提供一个自身静态私有的成员变量;
3、提供一个公有的静态公有的方法。