java基础

1.JDK安装

安装省略。

配置环境变量:

​ 目的:在任何目录下都可以执行java相关的命令。

  1. 我的电脑右键【属性】

  2. 【高级系统设置】

  3. 【环境变量】

  4. 用户变量和系统变量两个地方都可以配置。区别用户变量只能给当前用户使用,其他用户不能使用。如果在系统变量中配置,所有的用户都可以使用。

  5. 【新建】输入【变量名】(自定义名称,建议使用JAVA_HOME)【变量值】(JDK安装的目录,bin的上层目录) D:\Program Files\Java\jdk1.8.0_144

  6. 【编辑】path

  7. 【新建】输入 %JAVA_HOME%\bin

  8. 启动cmd 输入 javac -version(检查java的编译版本) , java -version(检查执行版本)

2.JDK安装目录简介

av[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uDH9upru-1648275882418)(images\image-20220106141338199.png)]

JDK: java开发环境

JRE: java的运行环境

JVM: java虚拟机,可以运行java程序的机器。

JDK中包含了JRE,JRE中包含了JVM.

3.java的跨平台机制(一处编写,到处运行)

VM : 虚拟机。由硬件和软件虚拟出来的机器。

JVM: 可以运行java程序的虚拟的机器。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a2E9DOUs-1648275882420)(images\image-20220106144751389.png)]

4.java中的数据类型

java中的数据类型划分:

  1. 基本数据类型:8个
  2. 引用数据类型: 类、接口、数组

一个字节由8bit位组成。

基本数据类型:

数据类型中文名字节数范围默认值
byte字节型1个字节-27~27-1(-128~127)0
short短整型2个字节-215~215-10
int整型4个字节-231~231-10
long长整型8个字节-263~263-10
float单精度4个字节0.0f
double双精度8个字节0.0d
char字符型2个字节\u00000
boolean布尔型1个字节true/falsefalse

数字:

​ 整数: byte ,short,int,long

​ 浮点数: float、double

​ 字符型 : char

布尔型: boolean

注意:

char 在java中使用单引号引起来的单个字符都是char

boolean 只有true和false两个值。

float和double都是不精确的数字。它们是一个约数,超过一定的范围会使用科学计数法。

public class Hello{
	public static void main(String[] args){
		float num1 = 1.23456789129F;
		float num2 = 1.23456789121F;
		
		System.out.println(num1 == num2);//true
	}
}

5.变量与常量

变量: 就是可以变化的量。

public class Hello{
	public static void main(String[] args){
		//定义变量
		int num = 123;
		System.out.println(num);
		num = 321;
		System.out.println(num);
	}
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QvMGKhJj-1648275882421)(images\image-20220106162855761.png)]

标识符: 类名,方法名,包名,变量名,常量名等统称为标识符。

标识符的定义规则与规范:

  1. 字母、数字、_下划线、$等(规则)¥

  2. 数字不能开头(规则)

  3. 不能是java中的关键字(规则)和保留字goto

  4. 严格区分大小写

  5. 长度不限

  6. 起名要有意义(见其名知其义)(规范)

    类名:每个单词首字母大写。

    包名:所有单词小写,包与包用.分层

    属性名(变量),方法名:首字母小写,从第二个单词开始,每个单词首字母大写.

    常量名:所有字母大写。

实例:

public class Demo1{
	public static void main(String[] args){
		int  num_12= 123;
		System.out.println("num12:" + num_12);
		//错误: 数字不能开头
		//int 1num =12;
		//System.out.println("num:" + 1num);
		//错误: 使用了关键字作为变量名
		//int byte = 321;
		//System.out.println("byte:" + byte);
		//BYTE不是关键字,区分大小写
		//int BYTE= 321;
		//System.out.println("BYTE:" + BYTE);
		
	}
}

变量定规则与规范:

  1. 标识符的定义规则

  2. 如果变量名由一个单词组成,建议全部字母小写。

    如果由多个单词组成,建议使用小驼峰法(xxxYyyZzz, xxx_yyy_zzz)

    public class Demo2{
    	public static void main(String[] args){
    		int num =  123;
    		System.out.println("num" + num);
    		//推荐使用的
    		//int studentCount =10;
    		//int student_count =10;
    		//不推荐使用的
    		//int StudentCount= 12;
    		System.out.println("学生个数:" + StudentCount);
    	}
    }
    

常量: 不可以被改变的量就是常量。常量使用final修改

字面常量: 就是字面意思

public class Demo3{
	public static void main(String[] args){
		//字面常量
		System.out.println("ABC");
		System.out.println(123);
	}
}

符号常量: 使用符号表示常量。

public class Demo4{
	public static void main(String[] args){
		//定义符号常量
		final int num = 123;
		//错误的: 不能给常量重新赋值
		num =123;
		System.out.println("num" + num);
	}
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VVOwzUP7-1648275882423)(images\image-20220106172036836.png)]

常量定规则与规范:

  1. 标识符的定义规则
  2. 常量全部的字母都要大写(XXX_YYY_ZZZ)
public class Demo4{
	public static void main(String[] args){
		//定义符号常量
		final int NUM = 123;
		//错误的: 不能给常量重新赋值
		//NUM =123;
		System.out.println("num" + NUM);
	}
}

6.内存溢出

public class Demo5{
	public static void main(String[] args){
		//2147483647 int类型的最大值
		int num =2147483647;
		System.out.println("int类型的最大值:"+num);
		num  = num +1;
		System.out.println("int类型的最大值+1后:"+num);//-2147483648
	}
}

int类型的最大值+1之后,值不仅没有变大,反而变为int类型的最小值了。这种现象就是内存溢出。

7.基本数据类型之间的相互转换

默认情况下,在java中小数是double,整数默认是int类型的。byte和short除外。

分类:

  1. 自动类型转换

    条件:①由小范围到大范围转换②数据类型要兼容

    自动类型转换示意图:箭头所指的方向都是自动类型转换

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P0q3ZqBr-1648275882424)(images\image-20220107092847230.png)]

    实例:

    public class Demo01{
    	public static void main(String[] args){
    		byte num1 = 123;
    		//向上发生自动类型转换
    		int num2 = num1;
    		
    		System.out.println("num1:"+num1+",num2:"+num2);
    	}
    }
    
    ​```java
    public class Demo02{
    	public static void main(String[] args){
    		float num1 = 2.3F;
    		//float  自动向 double转换
    		double num2 = num1;
    		System.out.println("num1:"+num1+",num2:"+num2);
    	}
    }
    ​```
    

特殊:

char自动向int转换:

public class Demo03{
	public static void main(String[] args){
		char ch = 'a';
		int num1 = ch;
		System.out.println("ch:"+ch+",num1:"+num1);
	}
}
public class Demo04{
	public static void main(String[] args){
		int num1= 123;
		//整型自动转换为 float
		float num2 = num1;
		System.out.println("num1:"+num1+",num2:"+num2);
	}
}

特殊中的特殊: long可以向float发送自动类型转换,但是可能会丢失精度

public class Demo05{
	public static void main(String[] args){
		long num1= 123131232123L;
		//long类型也可以向float发生自动类型转换
		float num2 = num1;
		System.out.println("num1:"+num1+",num2:"+num2);
	}
}
  1. 强制类型转换:转换示意图箭头的反方向就是强制转换

语法:

转换后的数据类型 变量名 = (转换后的数据类型 ) 转换前的数据;

条件:由小范围大大范围转换,数据类型要兼容。

public class Demo06{
	public static void main(String[] args){
		
		int num1 = 127;
		//强制将int 转换为 byte
		byte num2 = (byte)num1;
		System.out.println("num1:"+num1+",num2:"+num2);
	}
}

错误演示:

public class Demo07{
	public static void main(String[] args){
		
		boolean flag= true;
		//错误: 类型不兼容
		int num1 = (int)flag;
		System.out.println("flag:"+flag+",num1:"+num1);
	}
}

总结: 无论是自动类型转换还是强制类型转换,都是数值之间的转换。boolean不能转。

8.运算符

  1. 赋值运算符 = +=(b+=c相当于b=b+c) -+ *= /= %=

    public class Demo08{
    	public static void main(String[] args){
    		int  num = 123;
    		System.out.println("num:"+num);
    	}
    }
    
  2. 一元运算符 +(正号) -(负号) !(取反)

public class Demo09{
	public static void main(String[] args){
		int  num = 123;
	    boolean flag= true;
		System.out.println(+num);
		System.out.println(-num);
		System.out.println(!flag);
	}
}
  1. 算术运算符

    +(加号)-(减号)*(乘号)/(除号) %(取余,取模)

    public class Demo10{
    	public static void main(String[] args){
    		int  num1 = 2;
    	    int  num2 = 3;
    		System.out.println("num1 + num2 =" +(num1 + num2));//5
    		System.out.println("num1 - num2 =" +(num1 - num2));//-1
    		System.out.println("num1 * num2 =" +(num1 * num2));//6
    		//整数除以整数结果永远是整数
    		System.out.println("num1 / num2 =" +(num1 / num2));//0
    		//取余
    		System.out.println("num1 % num2 =" +(num1 % num2));//2
    	}
    }
    
  2. 关系运算符(比较运算符)

    >    >=    <   <=   !=   ==
    

    关系运算符返回的结果都是boolean,经常在分支结构或循环结构中使用

    public class Demo11{
    	public static void main(String[] args){
    		int  num1 = 2;
    	    int  num2 = 3;
    		System.out.println("num1 > num2 :" +(num1 > num2));//false
    		System.out.println("num1 >= num2 :" +(num1 >= num2));//false
    		System.out.println("num1 < num2 :" +(num1 < num2));//true
    		System.out.println("num1 <= num2 :" +(num1 <= num2));//true
    		System.out.println("num1 != num2 :" +(num1 != num2));//true
    		System.out.println("num1 == num2 :" +(num1 == num2));//false
    	}
    }
    
  3. 自增自减运算符 ++ –

    public class Demo12{
    	public static void main(String[] args){
    		int  num1 = 2;
    		//System.out.println(++num1);//3
    		System.out.println(num1++);//2
    		System.out.println(num1);//3
    	}
    }
    

    ++ 如果在变量的前面,则变量先+1 ,然后再参与其他的运算,如果在变量的后面,则现参与其他的运算,然后自身在+1;

  4. 逻辑运算符

    &&(短路与,and) &(普通与,and) || (断路或,or) | (普通或,or) !(取反,not) ^(异或 两边相同false 两边不同 true)

flag1flag2&&&|||!flag1
truetruetruetruetruetruefalse
truefalsefalsefalsetruetrueflase
falsefalsefalsefalsefalsefalsetrue
falsetruefalsefalsetruetruetrue
  ```java
  public class Demo13{
  	public static void main(String[] args){
  		System.out.println(true && true);//true
  		System.out.println(false && true);//false
  		System.out.println(true || true);//true
  		System.out.println(false || true);//true
  		
  	}
  }
  ```

演示 && 和 & 的区别:

public class Demo13{
	public static void main(String[] args){
		System.out.println((2>3) && (3/0==1));//false
		System.out.println((2>3) & (3/0==1));//by zero
	}
}

&& 具有断路功能,当第一个条件返回false的时候,第二个条件就不在执行。作为条件是推荐使用。

& 无论第一个条件是否成立,第二个条件都会执行。&还可以作为二进制运算符。&还可以作为路径参数的分隔符

public class Demo14{
	public static void main(String[] args){
		System.out.println((2<3) || (3/0==1));//true
		System.out.println((2<3) | (3/0==1));//by zero
	}
}

|| 和 | 的区别:

|| 具有断路功能,当第一个条件返回true,后面的条件就不执行了,作为条件是推荐使用。

| 无论第一个条件是否成立,第二个条件都会执行。&还可以作为二进制运算符。

  1. 位运算符(二进制运算符,了解即可)

    &(按位与)、|(按位或)、^(异或,相同为0,不同为1)

    ~(取反)、<<(左移位)、>>(右移位)、>>>(无符号右移)

    public class Demo15{
    	public static void main(String[] args){
    		System.out.println(5&7);//5
    		System.out.println(5|7);//7
    		System.out.println(5>>1);//2
    		System.out.println(5<<1);//10
    		System.out.println(5^3);//6
    		
    	}
    }
    

9.流程控制(程序结构)

无论哪种结构都只有一个入口,一个出口

  1. 顺序结构

  2. 分支结构(选择结构)

    if语句

    if…else…语句

    if…else if …else…

    switch结构

  3. 循环结构

    for循环

    while循环

    do…while…

9.0.Scanner类的使用

//导入Scanner类
import java.util.Scanner;
public class Demo17{
	public static void main(String[] args){
		System.out.println("请输入一个整数:");
		//创建Scanner类的对象
		Scanner  input= new Scanner(System.in);
		//接收控制台输入的int类型数据
		int num = input.nextInt();
		System.out.println("输入的整数:"+num);
		System.out.println("请输入你的名字:");
		String name= input.next();
		System.out.println("我叫:"+name);
	}
}

9.1.分支结构

if结构:

语法:

if(条件){
    
    //条件成立时执行的语句
}
public class Demo16{
	public static void main(String[] args){
		int num =10;
		if(num<10){
			System.out.println("num的值小于10");
		}
		if(num==10){
			System.out.println("num的值等于10");
		}
		if(num>10){
			System.out.println("num的值大于10");
		}
	}
}

实例:

//请输入一个正整数,判断是偶数还是奇数
import java.util.Scanner;
public class Demo18{
	public static void main(String[] args){
		System.out.println("请输入一个整数:");
		//创建Scanner类的对象
		Scanner  input= new Scanner(System.in);
		//接收控制台输入的int类型数据
		int num = input.nextInt();
		if(num%2==0){
			System.out.println(num+"是偶数");
		}
		if(num%2!=0){
			System.out.println(num+"是奇数");
		}
	}
}

if…else…结构:

语法:

if(条件){
    //条件成立时执行的语句
}else{
    //条件不成立时执行的语句
}
//请输入一个正整数,判断是偶数还是奇数
import java.util.Scanner;
public class Demo19{
	public static void main(String[] args){
		System.out.println("请输入一个整数:");
		//创建Scanner类的对象
		Scanner  input= new Scanner(System.in);
		//接收控制台输入的int类型数据
		int num = input.nextInt();
		if(num%2==0){
			System.out.println(num+"是偶数");
		}else{
			System.out.println(num+"是奇数");
		}
		
	}
}

if…else if…else结构:

if(条件1){
    //条件1成立时执行的语句
}else if(条件2){
     //条件2成立时执行的语句
}...
[else{
    //其他情况执行的语句
}]
//请输入一个正整数,判断是偶数还是奇数
import java.util.Scanner;
public class Demo20{
	public static void main(String[] args){
		System.out.println("请输学习成绩:");
		//创建Scanner类的对象
		Scanner  input= new Scanner(System.in);
		//接收控制台输入的int类型数据
		int score = input.nextInt();
		if(score>=90 && score<=100){
			System.out.println("奖励IPhone笔记本");
		}else if(score>=70 && score<80){
			System.out.println("奖励MP4");
		}else if(score>=80 && score<90){
			System.out.println("奖励IPhone手机");
		}else{
			System.out.println("加油");
		}
		
	}
}

注意: 条件的编写顺序,如果不想考了顺序给定一个区间

switch结构:

语法:

switch(表达式){

​ case 匹配值1:

​ //语句1

​ break;

​ case 匹配值N:

​ //语句N

​ break;

​ default:

​ //其他情况

​ break;

}

实例:

package com.bh;

import java.util.Scanner;

import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter.DEFAULT;

/**
 * 
 * @author qwy
 * 输入一个月数,判断哪个季节
 * 345  春季
 * 12 1  2  冬季
 * 
 */
public class Demo1 {
	public static void main(String[] args) {
		System.out.println("请输入一个月份:");
		Scanner input = new Scanner(System.in);
		int month=input.nextInt();
		switch(month){
		case 1:
			System.out.println("冬季");
			break;
		case 2:
			System.out.println("冬季");
			break;
		case 3:
			System.out.println("春季");
			break;
		case 4:
			System.out.println("春季");
			break;
		case 5:
			System.out.println("春季");
			break;
		case 6:
			System.out.println("夏季");
			break;
		case 7:
			System.out.println("夏季");
			break;
		case 8:
			System.out.println("夏季");
			break;
		case 9:
			System.out.println("秋季");
			break;
		case 10:
			System.out.println("秋季");
			break;
		case 11:
			System.out.println("秋季");
			break;
		case 12:
			System.out.println("冬季");
			break;
		
		default:
			System.out.println("输入月份不正确");
			break;
		}
		
		System.out.println("程序结束");
	}
}

简化实例:

package com.bh;

import java.util.Scanner;

import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter.DEFAULT;

/**
 * 
 * @author qwy
 * 输入一个月数,判断哪个季节
 * 345  春季
 * 12 1  2  冬季
 * 
 */
public class Demo2 {
	public static void main(String[] args) {
		System.out.println("请输入一个月份:");
		Scanner input = new Scanner(System.in);
		int month=input.nextInt();
		switch(month){
		case 12:	
		case 1:
		case 2:
			System.out.println("冬季");
			break;
		case 3:	
		case 4:	
		case 5:
			System.out.println("春季");
			break;
		case 6:	
		case 7:	
		case 8:
			System.out.println("夏季");
			break;
		case 9:	
		case 10:	
		case 11:
			System.out.println("秋季");
			break;
		
		default:
			System.out.println("输入月份不正确");
			break;
		}
		
		System.out.println("程序结束");
	}
}

注意break关键字的使用,break表示跳出整个switch结构。

switch结构的括号中的表达式的数据类型。

JDK1.5之前只能是 int类型。

JDK1.5开始可以使用int类型,enum(枚举类型)

JDK1.7开始可以使用int类型,enum(枚举类型),String(字符串)

char类型,short类型,long类型可以使用吗?

char类型,short类型可以,自动类型转换

long类型 不可以。

9.2.循环结构

  1. for循环
  2. while循环
  3. do…while…循环

循环三要素:

  1. 循环初始变量
  2. 循环条件
  3. 循环条件的改变

for循环:

语法:

for(循环初始变量;循环条件;循环条件的改变){

   //循环体
}
package com.bh;
/**
 * 使用for循环遍历1~100的所有偶数
 * @author qwy
 *
 */
public class Demo6 {
	public static void main(String[] args) {
		for (int i=1;i<=100; i++ ) {
			if(i%2==0){
				System.out.println("i="+i);
			}
		}

	}
}

while循环:

语法:

while(循环条件){
   //循环体
   //循环条件的改变
}
package com.bh;

public class Demo8 {
	public static void main(String[] args) {
		int i=1;
		while(i<=10){
			System.out.println(i);
			i++;
		}
	}
}

do…while循环:

语法:

do{
   //循环体
   //条件改变
}while(循环条件);

注意最后为值得分号。

package com.bh;

public class Demo9 {
	public static void main(String[] args) {
		int i=1;
		do{
			System.out.println(i);
			i++;
		}while(i<=10);
	}
}

while和do…while的区别:

while先判断,条件成立再执行。如果条件不成立一次都不执行。

do…while 先执行一次,然后再判断,条件成立继续执行,不成立最少执行一次。

9.3.break和continue关键字

package com.bh;

public class Demo10 {
	public static void main(String[] args) {
		for (int i = 0; i <10; i++) {
			if(i==5){
				break;
			}
			System.out.println(i);
		}
		System.out.println("结束循环");
	}
}

package com.bh;

public class Demo10 {
	public static void main(String[] args) {
		for (int i = 0; i <10; i++) {
			if(i==5){
				//break;
				continue;
			}
			System.out.println(i);
		}
		System.out.println("结束循环");
	}
}

break直接跳出整个循环,continue结束本次循环,进入下一次循环。

两个循环嵌套,外层循环一次,内层循环一周。

for(int j=1;j<=9;j++){
			for(int i=1;i<=j;i++){
				System.out.print(i+"*"+j+"="+(i*j)+"\t");
			}
			System.out.println();//换行
}
  • break和continue可以结束指定循环

    name: for (int i = 0; i <5; i++) {
        for(int j = 0; j < 5; j++){
    				break name;
    			}
    			System.out.println(i);			
    		}
    		System.out.println("结束循环");
    

10.数组

数组就是一组数据的组合。可以同时存放多个值。

数组的分类:

按照维度: 一位数组,二维数组,多维数组

按照数据类型: 整形数组,字符串数组,字节数组…

按照定义方式: 动态数组、静态数组

1.动态定义一维整型数组。

语法:

数据类型[] 数组名称 = new 数据类型[数组长度];

注意:数组的长度必须是int类型的

​ 数据类型:指的是数组中保存数据的类型

​ 数组元素 :指的是数组中的数据

​ 数组的索引值(下标,index):指的是数组中元素所在的位置,从0开始,最大值为数组的长度-1

2.获取数组中元素的值

语法:

数组名称[index]

  1. 给数组中的元素赋值

    数组名称[index] = 值;

实例:

package com.bh;
/**
 * 假如班级中有5个学生,将5个学生的成绩保存到数组中
 * @author qwy
 *
 */
public class Demo1 {
	public static void main(String[] args) {
		//定义数组
		int[]  score = new int[5];
		//给数组中的元素赋值
		score[0]=99;
		score[3]=100;
		//获取数组中的第一个值
		System.out.println(score[0]);
		//获取数组中的第二个值
		System.out.println(score[1]);
		//获取数组中的第四个值
		System.out.println(score[3]);
		
		System.out.println(score);
	}
}

image-20220110162658906

3.数组的遍历

package com.bh;
/**
 * 假如班级中有5个学生,将5个学生的成绩保存到数组中
 * @author qwy
 *
 */
public class Demo2 {
	public static void main(String[] args) {
		//定义数组
		int[]  score = new int[5];
		//给数组中的元素赋值
		score[0]=99;
		score[1]=98;
		score[2]=95;
		score[3]=99;
		score[4]=100;
      int[]  score = {99,98,95,99,100};
		
		//数组的遍历
		
/*		System.out.println(score[0]);
		System.out.println(score[1]);
		System.out.println(score[2]);
		System.out.println(score[3]);
		System.out.println(score[4]);*/
		//使用for循环遍历数组
		for(int i=0;i<5;i++){  //for(int i=0;i<score.length;i++)
			System.out.println(score[i]);
		}
	
	}
}

4.使用foreah遍历数组(增强型for循环)

for(数据类型  变量名:  数组){
	//循环体

}
//数据类型指的是数组中元素的类型
package com.bh;
/**
 * 假如班级中有5个学生,将5个学生的成绩保存到数组中
 * @author qwy
 *
 */
public class Demo3 {
	public static void main(String[] args) {
		//定义数组
		int[]  score = new int[5];
		//给数组中的元素赋值
		score[0]=99;
		score[1]=98;
		score[2]=95;
		score[3]=99;
		score[4]=100;
		
		//数组的遍历
		
/*		System.out.println(score[0]);
		System.out.println(score[1]);
		System.out.println(score[2]);
		System.out.println(score[3]);
		System.out.println(score[4]);*/
		//使用foreach循环遍历数组
		for(int sc : score){
			System.out.println(sc);
		}
	
	}
}

  1. 获取数组的长度

    语法:

    数组名称.length

    package com.bh;
    /**
     * 假如班级中有5个学生,将5个学生的成绩保存到数组中
     * @author qwy
     *
     */
    public class Demo5 {
    	public static void main(String[] args) {
    		//定义数组
    		int[]  score = new int[5];
    		//给数组中的元素赋值
    		score[0]=99;
    		score[1]=98;
    		score[2]=95;
    		score[3]=99;
    		score[4]=100;
    		//获取数组的长度
    		System.out.println(score.length);
    		System.out.println("***************");
    		for(int i=0;i<score.length;i++){
    			System.out.println(score[i]);
    		}
    		
    	
    	}
    }
    
    
  2. 数组的越界问题

    package com.bh;
    /**
     * 假如班级中有5个学生,将5个学生的成绩保存到数组中
     * @author qwy
     *
     */
    public class Demo4 {
    	public static void main(String[] args) {
    		//定义数组
    		int[]  score = new int[5];
    		//给数组中的元素赋值
    		/*score[0]=99;
    		score[1]=98;
    		score[2]=95;
    		score[3]=99;
    		score[4]=100;*/
    		//java.lang.ArrayIndexOutOfBoundsException: 5  数组越界异常
    		score[5]=87;
    		
    
    		//使用foreach循环遍历数组
    		for(int sc : score){
    			System.out.println(sc);
    		}
    	
    	}
    }
    
    
  3. 数组中常用几个操作

    最大值,最小值,和,平均值

    package com.bh;
    /**
     * 假如班级中有5个学生,将5个学生的成绩保存到数组中
     * @author qwy
     *
     */
    public class Demo6 {
    	public static void main(String[] args) {
    		//定义数组
    		int[]  score = new int[10];
    		//给数组中的元素赋值
    		score[0]=99;
    		score[1]=98;
    		score[2]=95;
    		score[3]=99;
    		score[4]=100;
    		score[5]=87;
    		score[6]=98;
    		score[7]=85;
    		score[8]=97;
    		score[9]=36;
    		
    		//假设第一个值就是最大值
    		int max=score[0];
    		for (int i = 0; i < score.length; i++) {
    			if(max<score[i]){//假设是错误的
    				max=score[i];
    			}
    		}
    		
    		System.out.println(max);
    		
    		//最小值
    		int min =score[0];
    		for (int i = 0; i < score.length; i++) {
    			if(min>score[i]){
    				min=score[i];
    			}
    		}
    		System.out.println(min);
    		//求和
    		int sum =0;
    		for (int i = 0; i < score.length; i++) {
    			sum +=score[i];
    		}
    		System.out.println(sum);
    		System.out.println(sum/10F);
    	
    	}
    }
    
    

    排序:(冒泡排序)

    package com.bh;
    /**
     * 假如班级中有5个学生,将5个学生的成绩保存到数组中
     * @author qwy
     *
     */
    public class Demo7 {
    	public static void main(String[] args) {
    		//定义数组
    		int[]  score = new int[10];
    		//给数组中的元素赋值
    		score[0]=99;
    		score[1]=98;
    		score[2]=95;
    		score[3]=99;
    		score[4]=100;
    		score[5]=87;
    		score[6]=98;
    		score[7]=85;
    		score[8]=97;
    		score[9]=36;
    		//两个循环嵌套,一个判断+ 位置交换
    		for (int i = 0; i < score.length; i++) {
    			for (int j = 0; j < score.length; j++) {
    				if(score[i]<score[j]){
    					int temp=score[i];
    					score[i]=score[j];
    					score[j]=temp;
    					
    				}
    			}
    		}
    		
    		for (int i = 0; i < score.length; i++) {
    			System.out.print(score[i]+"\t");
    		}
    		
    	}
    }
    
    
  4. 静态定义一维数组

    语法:

    数据类型[] 数组名= {值列表}

    package com.bh;
    
    public class Demo01 {
    	public static void main(String[] args) {
    		//静态定义数组,此时一定不要指定长度
    		//int[] score =new int[]{99,98,100,95,94};
    		//简化
    		int[] score ={99,98,100,95,94};
    	}
    }
    
    
    package com.bh;
    
    public class Demo01 {
    	public static void main(String[] args) {
    		//静态定义数组,此时一定不要指定长度
    		//int[] score =new int[]{99,98,100,95,94};
    		//简化
    		int[] score ={99,98,100,95,94};
    		
    		for (int i = 0; i < score.length; i++) {
    			System.out.println(score[i]);
    		}
    	}
    }
    
    

    内存图:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6MkVmEcN-1648275882427)(images\1641868857296.png)]

  5. 动态定义二维数组

    二维数组其实就是数组中的元素还是数组。在java的内存中不存在二维数组。

    package com.bh;
    
    /**
     * 有三个班级,每个班级有5个学生 注意一维数组的位置必须指定长度,二维数组的位置可以不指定长度 此刻一维数组表示的是班级, 二维数组的位置表示的班级人数
     * 
     * 先创建班级
     * 
     * @author qwy
     *
     */
    public class Demo02 {
    	public static void main(String[] args) {
    		int[][] scores = new int[3][5];
    		System.out.println(scores[0]);
    		// 创建第一个班级的人数
    		int[] clazz1 = new int[5];
    		System.out.println(clazz1);
    		scores[0] = clazz1;
    		System.out.println(scores[0]);
    		// 创建第二个班级的人数
    		int[] clazz2 = new int[5];
    
    		scores[1] = clazz2;
    
    		// 创建第三个班级的人数
    		int[] clazz3 = new int[5];
    
    		scores[2] = clazz3;
    
    	}
    }
    
    

    示意图:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tieu8ivX-1648275882428)(images\1641871577198.png)]

  6. 二维数组的赋值与取值

package com.bh;

/**
 * 有三个班级,每个班级有5个学生 注意一维数组的位置必须指定长度,二维数组的位置可以不指定长度 此刻一维数组表示的是班级, 二维数组的位置表示的班级人数
 * 
 * 先创建班级
 * 
 * @author qwy
 *
 */
public class Demo03 {
	public static void main(String[] args) {
		int[][] scores = new int[3][5];
		// 创建第一个班级的人数
		int[] clazz1 = new int[5];
		
		scores[0] = clazz1;
		
		// 创建第二个班级的人数
		int[] clazz2 = new int[5];

		scores[1] = clazz2;

		// 创建第三个班级的人数
		int[] clazz3 = new int[5];

		scores[2] = clazz3;
		
		//**************给二维数组赋值***********************
		scores[0][0]=99;
		scores[2][2]=100;
		
		//*************获取数组中的值****************
		
		System.out.println(scores);//获取一维数 一维数组的引用
		System.out.println(scores[0]);//获取第一个二维数组的引用
		System.out.println(scores[1]);
		System.out.println(scores[2]);
		
		System.out.println(scores[0][0]);//获取第一个班级的第一个学生
		System.out.println(scores[0][1]);//获取第一个班级的第二个学生
		
		System.out.println(scores[2][2]);//获取第三个班级的第三个学生

	}
}

  1. 二维数组的遍历

    package com.bh;
    
    /**
     * 有三个班级,每个班级有5个学生 注意一维数组的位置必须指定长度,二维数组的位置可以不指定长度 此刻一维数组表示的是班级, 二维数组的位置表示的班级人数
     * 
     * 先创建班级
     * 
     * @author qwy
     *
     */
    public class Demo04 {
    	public static void main(String[] args) {
    		int[][] scores = new int[3][5];
    		// 创建第一个班级的人数
    		int[] clazz1 = new int[5];
    		
    		scores[0] = clazz1;
    		
    		// 创建第二个班级的人数
    		int[] clazz2 = new int[5];
    
    		scores[1] = clazz2;
    
    		// 创建第三个班级的人数
    		int[] clazz3 = new int[5];
    
    		scores[2] = clazz3;
    		
    		//**************给二维数组赋值***********************
    		scores[0][0]=99;
    		scores[2][2]=100;
    		
    		//*************二维数组的遍历****************
    		
    		for (int i = 0; i < scores.length; i++) {
    			//System.out.println(scores[i]);
    			int[] clazz=scores[i];
    			//System.out.println(clazz);
    			for(int j=0;j<clazz.length;j++){
    				System.out.print(clazz[j]+"\t");
    			}
    			System.out.println();
    		}
    		System.out.println("*****************");
    
    		for (int i = 0; i < scores.length; i++) {
    			
    			for(int j=0;j<scores[i].length;j++){
    				System.out.print(scores[i][j]+"\t");
    			}
    			System.out.println();
    		}
    	}
    }
    
    
  2. 数组的操作工具类Arrays

    package com.bh;
    
    import java.util.Arrays;
    
    public class Demo06 {
    	public static void main(String[] args) {
    		int[] score={12,34,56,21,98,23};
    		/*for (int i = 0; i < score.length; i++) {
    			for (int j = 0; j < score.length; j++) {
    				if(score[i]<score[j]){
    					int temp=score[i];
    					score[i]=score[j];
    					score[j]=temp;
    				}
    			}
    		}*/
    		//排序的方法
    		/*Arrays.sort(score);
    		
    		
    		for (int i = 0; i < score.length; i++) {
    			System.out.print(score[i]+"\t");
    		}*/
    		//获取制定值出现的索引位置
    		int binarySearch = Arrays.binarySearch(score, 56);
    		System.out.println(binarySearch);
    	}
    }
    
    
//可变参数
//	public double add(String a ,double... num1  ) {
//		return num1 + num2;
//	}

11.方法

方法就是可以被重复调用的代码块。

为什么要使用方法?

我们可以在需要使用的地方来多次调用,不用重复去编写。

方法定义语法:在java中方法在类中定义

访问修饰符  [staitc]  返回类型  方法名(参数列表){
    
    //方法体
    [return 值;]
}

方法分类:

  1. 无参无返回值
  2. 无参有返回值
  3. 有参无返回值
  4. 有一个参数无返回值
  5. 有多个参数无返回值
  6. 有参数有返回值

方法的执行:所有的方法必须被调用才能执行,包括主方法。主方法(main)被JVM调用。 其他的方法要执行必须被主方法直接或间接调用。

方法的参数:

  1. 形参(形式参数):方法的定义处的参数称为形参

  2. 实参(实际参数):方法的调用处的参数称为实参

参数作用就是用来传递数据,实参向形参传值,(调用处向被调用处传值)
package com.bh;

public class Demo2 {
	
	//定义一个无参无返回值的方法
	public static void noParamNoReturn(){
		System.out.println("我是无参无返回值的方法");
	}
	
	//定义一个无返回值,有一个参数的方法
	public static void oneParamNoReturn(String name){
		System.out.println("无返回值,有一个参数的方法,我叫:"+name);
	}
	//定义一个无返回值,多个参数的方法
	public static void moreParamNoReturn(String name,int age){
		System.out.println("无返回值,有多个参数的方法,我叫:"+name+",年龄是:"+age);
	}
	//定义有返回值,无参的方法
	public static String noParamHasRturn(){
		System.out.println("无参数有返回值的方法");
		return "abc";
	}
	//定义有返回值,有以一个参数的方法
	public static int  oneParamHasReturn(String name){
		System.out.println("有返回值,有以一个参数的方法,我叫:"+name);
		
		return  2+5;
	}
	//有返回值,多个参数的方法
	public static String moreParamHasReturn(String name,int age,String sex){
		System.out.println("有返回值,多个参数的方法,我叫:"+name+",性别:"+sex+",年龄:"+age);
		return  name+":"+age+":"+sex;
	}
	public static void main(String[] args) {
		//调用无参无返回值的方法
		//noParamNoReturn();
		//调用无返回值,有一个参数的方法
		//oneParamNoReturn("admin");
		
		//调用无返回值,多个参数的方法
		//moreParamNoReturn("张三", 18);
		//调用有返回值,无参的方法,并接收返回结果(结果不使用时,可以不接收)
		String noParamHasRturn = noParamHasRturn();
		System.out.println(noParamHasRturn);
		
		//调用有返回值,有以一个参数的方法 
		
		int oneParamHasReturn = oneParamHasReturn("李四");
		System.out.println(oneParamHasReturn);
		
		//调用有返回值,多个参数的方法
		
		String moreParamHasReturn = moreParamHasReturn("王五", 12, "女");
		System.out.println(moreParamHasReturn);
	}
	
}

1.方法名定义规则与规范:

  1. 标识符的定义规则
  2. 使用小驼峰法(xxxYyyZzz,xxx_yyy_zzz)

2.局部变量、全局变量、参数、返回值

/**

  • 变量:
  • 1.定义在类体中的 变量 叫做 属性 (全局)(成员变量 成员属性 )
  • 2.定义在方法体中的变量 叫做 局部变量
  • 全局变量:
    • 定义在类体中 有默认值 没有作用域限制 由对象调用
  • 局部变量:
    • 定义在方法体中 没有默认值 有作用域限制(从声明开始,到所在大括号结束)
    • 直接调用 在使用和访问之前要先进行赋值
  • 参数: 定义在 方法 小括号中的变量
    • 特殊的局部变量
      *在使用和访问之前可以 先不赋值
      *当调用此参数的方法的时候 进行 赋值
      *作用:将方法外部的值 传递到 方法内部使用
    • *返回值: return 后面的值 叫做返回值
    • 在方法内部写 如 return 15 ;
      *作用:将方法内部的值 传递到外部使用
    • 值传递给方法的调用者
      *
  • 在内部和外部互相传递值的时候 可以通过参数和返回值 还可以通过 属性传递
  • 但是 因为封装 属性一般都是 私有的 所以 参数和返回值 传递值的时候 较多
    *
    */

12.方法的重载(overload)

重载:在同一个类中,同名不同参数(方法名相同,参数不同(参数的个数,参数的类型不同,参数的类型顺序不同)),返回值无关

重载就是提高方法名的利用率。

方法调用时,怎么调用?

  1. 首先根据方法名找到要调用的方法。如果没有相同的方法名(只找到一个),直接调用就行
  2. 如果找到多个方法名一样的方法,则再根据参数决定调用哪个
package com.bh;

public class Demo3 {
	public static void main(String[] args) {
		
		add();
		add(1F);
	}
	
	public static void add(){
		int num1=2;
		int num2=3;
		System.out.println(num1+num2);
	}
	
	public static void add(int num1){
		
		int num2=3;
		System.out.println(num1+num2);
	}
	
	public static int add(int num1,int num2){
		return 12;
	}
	public static int add(int num1,float num2){
		return 12;
	}
	
	public static int add(float num2){
		return 12;
	}
	public static int add(float num2,int num1){
		return 12;
	}
	
	
}	

13.面向对象

java是一个面向对象的语言。

面向问题->面向过程->面向对象。

面向对象:其实就是一种思想,关注程序实现的对象。

面向过程:关注程序实现的过程。

类: 就是对客观存在事物的一类抽象的描述。是一个抽象的概念。

​ 描述: 特征(属性,成员变量) ,行为(方法)

对象:类的具体化,客观存在的事物。

类是对象的抽象,对象是类的具体化。

面向对象的特征: 封装、继承、多态

在一个类中 使用 其他包中的 资源 需要 导包

/*

  • 1.什么是面向对象 ?
  • 面向对象:其实就是一种 思想 更加关注 对象的思想
  • 面向过程: 关注 程序 实现的 过程
  • 2.什么是对象?
  • 客观存在的某个事物 都是一个对象
  • 万物皆对象
  • 3.什么是类?(类别)
  • 4.类和对象的关系?
  • 1. 类是大量对象共性的抽象概念
    
  • 2.类是创建对象的模板
    
  • 3.类是客观事物在人脑中的主观反应
    
  • 4.对象是类的具体 实例
    
    1. 代码中如何声明一个类
  • yes
    
    1. 类是由什么组成
  • yes
    1. 创建对象的语法
  • Cat  c = new Cat();
    
  • new Cat()   创建的一个新对象
    
  • c 变量名
  •  Cat  声明变量的数据类型  由类名 充当 也叫 类类型
    
  • 右–》左 在Cat类中 拿出一个 具体的 Cat
  •    并让  Cat 类型的 变量c 去 引用
    
      1. 属性 就是用来 描述 对象特征的 全局变量
  • 9.方法 用来描述对象的行为
  • void 代表的是 没有 返回值
  • 【修饰符 】 返回值类型 方法名 ( 【参数】 ){
  •  完成此方法的 代码
    
  • }

定义类:使用class关键字

语法:

访问修饰  class   类名{
    //特征(属性)
    //行为(方法)
}

定义类:

package com.bh2;
//定义类
public class Person {
	//定义属性
	String name;
	int age;
	String sex;
	
	//定义方法
	public void sayHello(){
		System.out.println("我叫:"+name+",年龄:"+age+",性别:"+sex);
	}
}

创建对象:new 类名()

package com.bh2;

public class Test {
	public static void main(String[] args) {
		//创建对象
		Person p= new Person();
		//调用属性,给属性赋值
		p.name="admin";
		p.age=12;
		p.sex="男";
		//调用方法
		p.sayHello();
      
		
	}
}

对象内存图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2S0ukvcr-1648275882430)(images\1641970011111.png)]

创建多个对象:

package com.bh2;

public class Test2 {
	public static void main(String[] args) {
		//创建对象
		Person p1= new Person();
		//调用属性,给属性赋值
		p1.name="张三";
		p1.age=12;
		p1.sex="男";
		//调用方法
		p1.sayHello();
		
		System.out.println("****************");
		
		
		Person p2= new Person();
		p2.name="李四";
		p2.age=13;
		p2.sex="女";
		p2.sayHello();
		
		
		
		
	}
}

示意图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zmPLrjYQ-1648275882431)(images\1641970737002.png)]

值传递:

package com.bh2;

public class Test3 {
	public static void main(String[] args) {
		//创建对象
		Person p1= new Person();
		//调用属性,给属性赋值
		p1.name="张三";
		p1.age=12;
		p1.sex="男";
		
		
		System.out.println("****************");
		
		
		Person p2= new Person();
		p2.name="李四";
		p2.age=13;
		p2.sex="女";
		
		p2=p1;
		
		//调用方法
		p1.sayHello();
		p2.sayHello();
		
		
		
		
	}
}

示意图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-80qQXh4t-1648275882432)(images\1641971277763.png)]

基本数据类型的传值:

package com.bh2;
//基本数据类型的传值
public class Test4 {
	public static void main(String[] args) {
		int num =123;
		printer(num);//123
		System.out.println("main方法的num:"+num);//123
		
	}
	
	public static void printer(int num){
		System.out.println("priter中的num:"+num);//123
		num=321;
		System.out.println("priter中重新赋值的num:"+num);//321
		
	}
}

实体图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O5esetkx-1648275882433)(images\1641972594985.png)]

引用数据类型的传值:

package com.bh2;
//引用数据类型的传值
public class Test5 {
	public static void main(String[] args) {
		Person p=new Person();
		p.age=12;
		
		printer(p);
		
		System.out.println("main方法的年龄:"+p.age);//13
		
	}
	
	public static void printer(Person person){
		int age = person.age;
		System.out.println("printer方法的年龄:"+age);//12
		person.age=13;
		System.out.println("printer方法修改后的年龄:"+age);//13
	}
}

示意图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lpkyiGRt-1648275882434)(images\1641973519883.png)]

总结:

  1. 如果传值为基本数据类型。则传递就是值本身,不会去其他方法造成影响(printer方法不会影响main方法)
  2. 如果传值为引用数据类型,则传递的是地址。如果对堆内存中的数据进行修改,会影响其他 方法中的数据,(printer方法中对person进行修改,会影响main方法中的person)

一个*.java文件中可不可以编写多个类(除了内部类外)?

可以,但是只能有一个被public修饰的类,而且这个public修饰的类必须和文件名一致。开发中不要在一个文件中编写多个类,即使编写了多个类,编译后还是一个类一个文件。

变量:

  • 1.定义在类体中的 变量 叫做 属性 (全局)(成员变量 成员属性 )
  • 2.定义在方法体中的变量 叫做 局部变量
  • 全局变量:
    • 定义在类体中 有默认值 没有作用域限制 由对象调用
  • 局部变量:
    • 定义在方法体中 没有默认值 有作用域限制(从声明开始,到所在大括号结束)
    • 直接调用 在使用和访问之前要先进行赋值
  • 参数: 定义在 方法 小括号中的变量
    • 特殊的局部变量
      *在使用和访问之前可以 先不赋值
      *当调用此参数的方法的时候 进行 赋值
      *作用:将方法外部的值 传递到 方法内部使用
      *返回值: return 后面的值 叫做返回值
      • 在方法内部写 如 return 15 ;
        *作用:将方法内部的值 传递到外部使用
      • 值传递给方法的调用者
        *
  • 在内部和外部互相传递值的时候 可以通过参数和返回值 还可以通过 属性传递
  • 但是 因为封装 属性一般都是 私有的 所以 参数和返回值 传递值的时候 较多

14.面向对象特征之封装

封装就是对实现细节进行隐藏。对外界不可见。

将属性和行为(方法)看做一个不可分割的整体。

1.权限修饰符

/

可以在一个java文件中 写 多个 class

但 最多 只能有一个 class被 public 修饰

并且被public修饰的类 要与文件名相同

封装 是两个过程

分别对属性和方法进行封装

规则:

属性私有化 方法公开化 提供get/set方法

private 私有的 只能在本类中访问

不写 (默认的 default friendly) 只能在本包中访问

protected 受保护的 本包 + 其他包的子类

public 公共的 哪都能方法

为什么要使用封装:

package com.bh3;

public class Test {
	public static void main(String[] args) {
		Person p= new Person();
		p.name="张三";
		p.age=10000;
		p.sex="人妖";
		
		p.sayHello();
	}
}

测试代码:

package com.bh3;

public class Test {
	public static void main(String[] args) {
		Person p= new Person();
		p.name="张三";
		p.age=10000;
		p.sex="人妖";
		
		p.sayHello();
	}
}

2.封装的步骤:

  1. 使用private关键字修饰属性或方法
  2. 提供公开的setter/getterr方法,供外界调用
package com.bh3;

public class Person {
	private String name;
	private int age;
	private String sex;
	//this表示本类的
	//setter
	public void setName(String name){
		this.name=name;
	}
	
	public void setAge(int age){
		if(age<0 || age>150){
			this.age=0;
		}else{
			this.age=age;
		}
		
	}
	public void setSex(String sex){
		this.sex =sex;
	}
	//getter方法
	
	public String getName(){
		return this.name;
	}
	public int getAge(){
		return this.age;
		
	}
	public String getSex(){
		return this.sex;
	}
	
	public void sayHello(){
		System.out.println("我叫:"+name+",性别:"+sex+",年龄:"+age);
	}
}

对于private关键字的理解:

private表示私有化的,对外界不可见,不能代表整个封装。

15.构造方法(构造器)

构造方法作用:

  1. 用来创建对象

  2. 可以给成员变量赋值

定义构造方法语法:

访问修饰  类名(参数列表){
    //方法体
}

构造方法编写规则:

  1. 构造方法名必须和类名一致
  2. 构造方法不能有返回类型,void也不行
  3. 构造方法不能使用 return 值

之前定义的类我们没有编写构造方法。但是也能使用new关键字创建对象?

如果一个类中没有显示的编写构造方法,则JVM在运行时会自动创建一个无参构造。如果我们显示的定义了其他的构造方法,则JVM不会再帮我们创建无参的构造方法。(一个类中必定有一个构造方法。)

带小括号的 一般是方法

不带小阔的 一般是属性

创建对象的时候 new 的 其实是 构造器(方法)

什么是构造器:

构造器就是用来创建对象 和初始化属性的 一种 特殊的方法

语法

【权限修饰符 】 类名(【参数】){

代码

}

一个类中 如果 不写构造器 那么 系统会 给我们一个 无参的构造器

如果写了构造器 那么系统就不再分配

构造器 是在 每次创建对象的时候 执行

package com.bh;
/**
 * shift + alt +s 
 * 接着按  r
 * shift + alt + a
 * 
 * @author qwy
 *
 */
public class Person {
	private int id;
	private String name;
	private int age;
	private String sex;
	
	//定义无参构造
	public Person(){
		System.out.println("无参构造方法");
	}
	
	//定义一个有参构造
	public Person(String name){
		System.out.println("我是一个有参数的构造:"+name);
	}
	//多个参数的构造方法
	public Person(int id,String name){
		System.out.println("多个参数的构造方法:id="+id+",name="+name);
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	
	
}

以上定义了3个构造方法。此三个构造方法也构成了重载

空指针异常:

package com.bh;

public class Test2 {
	public static void main(String[] args) {
		Person p=null;
		p.name="afa";//java.lang.NullPointerException空指针异常
		p.sayHello();//java.lang.NullPointerException空指针异常
	}
}

使用构造方法给成员变量赋值

	public Person(String name){
		//this此时表示的调用成员变量
		this.name=name;
		System.out.println("我是一个有参数的构造:"+this.name);
	}
//定义处	
public Person(int id,String name,String sex){
		this.id=id;
		this.name=name;
		this.sex=sex;
		System.out.println("多个参数的构造方法:id="+id+",name="+name);
	}

//主方法
	Person p= new Person(1, "haha","男");
	p.sayHello();

多参数构造方法创建对象内存图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mBJoOZt5-1648275882435)(images\1642038761283.png)]

16.面向对象特征之继承

继承的目的:将重复的代码在父类中编写,然后让子类继承父类,父类中的属性和方法就会被子类继承。

父类:超类

子类: 扩展类

语法:

父类{}

子类 extends 父类{}

  1. 子类继承了那些东西? 属性和方法被继承,构造方法没有被继承,而是被调用

  2. 子类创建对象的过程

    首先在子类的构造方法的第一行调用父类的构造方法。

    当父类构造方法执行完毕后,子类的构造方法才执行完。

​ 父类:

package com.bh4;

public class Person {
   private int id;
   private String name;
   private String sex;
   private int age;
   public Person() {
   	System.out.println("Person.Person()-----父类无参构造");
   }
   public int getId() {
   	return id;
   }
   public void setId(int id) {
   	this.id = id;
   }
   public String getName() {
   	return name;
   }
   public void setName(String name) {
   	this.name = name;
   }
   public String getSex() {
   	return sex;
   }
   public void setSex(String sex) {
   	this.sex = sex;
   }
   public int getAge() {
   	return age;
   }
   public void setAge(int age) {
   	this.age = age;
   }
   
   
   public void sayHello(){
   	System.out.println("Student.sayHello()");
   	System.out.println("我叫:"+name+",年龄:"+age);
   }
}

子类:

package com.bh4;

public class Student extends Person{
   public Student() {
   	//调用父类的无参构造方法
   	super();
   	System.out.println("Student.Student()-----学生子类无参构造");
   	
   }

}

测试类:

package com.bh4;



public class Test {
	public static void main(String[] args) {
		Student s= new Student();
	}
}

打印结果:

Person.Person()-----父类无参构造
Student.Student()-----学生子类无参构造

总结: 首先执行完了父类的构造方法,然后子类的构造方法才执行完。如果子类的构造方法中没有显示的调用父类的构造方法,则默认在在子类的构造方法的第一行默认有super() 表示调用父类的无参构造,如果在父类中手动编写了其他的构造方法,则可能会报错。所以开发中一般情况都建议保留无参构造。

  1. 子类独有的属性和方法

    子类独有的属性和方法应该在子类中去编写。

    package com.bh5;
    
    public class Student extends Person{
    	//学生独有的属性
    	private int score;
    	
       //学生独有的方法
    	public int getScore() {
    		return score;
    	}
    
    	public void setScore(int score) {
    		this.score = score;
    	}
    	
    
    }
    
    

    子类对象调用自己独有的方法

    		Student s= new Student();
    		s.setId(1);
    		s.setName("A学生");
    		s.setAge(12);
    		s.setSex("男");
    		//调用子类独有的方法
    		s.setScore(100);
    

1.方法的重写(override,overwrite)【覆写】

重写: 在不同的类中(父类和子类,接口和实现类),子类对父类方法的重写编写。同名同参同返回值(方法名相同,参数相同【个数相同,类型相同,类型的顺序相同】),子类的访问修饰不能比父类更加严格。

private>protected>缺省>public.

经常在方法的上面使用@Override。标注,用来检查是否正确,该注解可以省略。

​ 重写后,执行的是子类自己的方法(被重写过的方法,父类方法不在执行)

注意和重载的区别

 ```java

package com.bh6;

public class Student extends Person {
private int score;
public Student() {
// TODO Auto-generated constructor stub
}
public Student(int id,String name,int age){
//调用父类的有参构造方法
super(id,name,age);
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
@Override
public void sayHello(){
//调用父类中的方法
super.sayHello();
System.out.println(“我的学习成绩是:”+score);
}
}

 ```

java中的继承只能是单继承。一个类只能有一个父类。但是可以多层继承。

/*

  • 继承 一个类 继承了 另一个类中 所有 非私有的 属性和方法
  • 父类中的属性和方法 在子类中 隐式存在
  • 重写 覆盖 Override
    • 就是 将父类中的方法 在子类中 重新写一遍
  • 重写就是将子类中 隐式 存在的方法 变为 显示存在
    • 目的:扩展功能
  • 重写 返回值是基本数据类型的时候 要跟父类的相同
  • 重写的方法 权限要大于 或等于 父类中 方法的权限
  • static和final 修饰的方法 不能被继承
  • 属性不能被重写
  • 向上转型 AAA b = new BBB();
    • 父类类型的变量 引用 子类的 对象
  • 向上转型后
  • 变量只能调用 父类和子类共有的属性和方法 执行的是重写后的方法
  • */
  1. Object类

    如果一个类没有显示的继承某个类。则它默认继承Object类。

​ toString()源码:

 public String toString() {
     return getClass().getName() + "@" + Integer.toHexString(hashCode());
 }

重写equals方法

@Override
	public boolean equals(Object obj) {
		if(obj instanceof Person){
			Person p=(Person) obj;
			if(p.getId()==this.id && p.getName().equals(this.name)){
				return true;
			}else{
				return false;
			}
		}else{
			return false;
		}
	}

继承 一个类 继承了 另一个类中 所有 非私有的 属性和方法

2.this和super

/

this 关键字 代表 当前对象

  • 哪个对象 调用此方法 this就代表了 哪个对象

this 的用法

  • ​ this可以调用 本类中的属性和方法
  • 可以省略不写
  • this也可以在构造器中 调用本类的属性和方法
  • this() 可以在构造器中 调用 其他的构造器 必须放在第一行
  • 构造器之间不能互相 调用
  • 构造器 不能 自己调用自己

super 关键字 代表的是 父对象

  • 调用的是 父类中的属性和方法
    • 构造器不能继承 但是 在子类的构造器中 会隐式存在super()
  • 当我们 自己写了 super()的时候 系统就不再提供
  • 也必须放在第一行

this()和super()不能 同时 存在

16.3向下转型 向上转型

java中类与类之间 是单继承关系
Object类是 所有类的 基类
类型转换
向上转型
Animal a = new Dog();
向上转型后 变量 调用的是 父类和子类共有的属性和方法
执行的是 子类重写后的方法
向下转型
SmallDog s = (SmallDog)a;

			s.nn();
			向下转型后  可以 调用子类 独有的属性和方法
package day0214b;
/*
  		java中类与类之间  是单继承关系
 		Object类是 所有类的 基类
   	类型转换
   		向上转型
   			Animal a = new Dog();
   			向上转型后  变量 调用的是 父类和子类共有的属性和方法
   						   执行的是 子类重写后的方法
   		向下转型
   			SmallDog s = (SmallDog)a;
				s.nn();
				向下转型后  可以 调用子类 独有的属性和方法
 
 */
public class TestAnimal {
	public static void main(String[] args) {
		
		Animal a = new SmallDog();
		System.out.println(a.i);
		a.mm();
		//防止 向下转型的时候  出现 类型转换异常
		//一般要进行一次判断  
		//判断 变量a所引用的 实例(对象)是不是SmallDog类型的 实例(对象)
		if(a instanceof SmallDog) {
			SmallDog s = (SmallDog)a;
			s.nn();
			System.out.println(s.i);
		}
		
		
	}
}
class Animal {
	int i = 5;
	void mm() {
		System.out.println(3);
	}
}
class  Dog extends Animal{
	//int i = 5;
	int i = 10;	
	void mm() {
		System.out.println(6);
	}	
}
class SmallDog extends Dog{
    //int i = 5;
	//int i = 10;	
	int i = 15;
	void mm() {
		System.out.println(9);
	}	
	void nn() {
		System.out.println(19);
	}	
	
}

17.static 静态修饰符

  • 可以修饰 *类 属性 方法

  • static 修饰的属性和方法

    • 叫做 类属性 和 类方法 与对象无关
    静态属性和  静态方法 可以用类名直接调用  
    
    在本类中使用时 类名可以省略
    
    非静态方法中  可以调用静态和非静态 的属性和方法
    
    静态方法中   只能调用静态的属性和方法  不能调用非静态
    
  • 原因:

    • 静态属性和方法 与对象无关 它属于 类
    非静态属性和方法    属于的是 对象
    
    任何对象 都可以修改  静态属性的值
    
    修改后的值  被 所有对象  共享
    
    • 静态方法不能被重写
  • 加载顺序 先静态 后 非静态

    • 程序执行的时候 最先加载 静态的属性和方法 并且只加载一次
    • 非静态的属性和方法 是在创建对象的时候 才加载 不创建对象 就没有

18.java.lang 包

18.1 String类的常用方法

是系统默认导入的一个包

用到此包下的所有类和接口的时候 不用 导包

1.包装类 可以将 基本数据类型的值 转换成 对象类型

​ 对象

​ 15 “15”

基本类型包装类类型

byte Byte

short Short

int Integer

long Long

float Float

double Double

boolean Boolean

char Character

package day0216a;

import java.util.Arrays;

/*
 * String 类   字符串类
 * 		 被final修饰  不能被  继承
 * 		"qwe" 字符串  既是常量  又是对象
 */
public class TestString {
	public static void main(String[] args) {
		String  s1 = "qwe";
		String  s2 = new String("qwe");
		byte[]  b1 = {97,98,99};
		String  s3 = new String(b1);
		char[]  c1 = {'a','b','c'};
		String  s4 = new String(c1);
		"qwe".hashCode();
		System.out.println("===========常用方法================");
		String str = "qweasdzxc";
		System.out.println(str.charAt(2));//e
		System.out.println(str.codePointAt(3));//97
		System.out.println(str.codePointBefore(4));//97
		//计算有多少个字符  3-1
		System.out.println(str.codePointCount(1, 3));//2
		/*
		 * 比较字符串顺序
		 * 		 x.compareTo(y)
		 * 		负数    x 在  y 前面
		 * 		正数    x 在  y 后面
		 * 		  0   x 和 y 相等
		 */
		System.out.println("bbb".compareTo("abbcd"));//-1
		System.out.println("Abb".compareToIgnoreCase("abbcd"));//-2
	
		System.out.println("abc".concat("def"));//abcdef
		System.out.println("abc"+"def" );//abcdef
		//判断是否包含
		System.out.println("abcdef".contains("cd"));//true
		System.out.println("abcdef".contains("ce"));//false
		
		//将字符数组转换成字符串
		char[]  ch = {'a','b','c','d','e','f'};
		System.out.println(String.copyValueOf(ch));//abcdef
		System.out.println(String.copyValueOf(ch,1,3));//bcd
		//以什么结尾
		System.out.println("biji.jpg".endsWith(".jpg"));//true
		//以什么开头
		System.out.println("biji.jpg".startsWith("bi"));//true
		//转换成字节数组
		String ss = "abc";
		byte[] by = ss.getBytes();// [97,98,99]
		for (byte b : by) {
			System.out.print(b+" ");
		}
		System.out.println();
		//将字符从此字符串复制到目标字符数组。
		char[] cc = new char[10];//目标数组
		String sss = "abcdefg";//源字符串
		sss.getChars(2, 5, cc, 1);
		for (char c : cc) {
			System.out.print(c+" ");
		}
		System.out.println();
		
		//查找子字符串在 源字符串首次出现的 索引
		//3 代表从 3索引处开始 查找  找不到返回-1
		String sss1 = "abcdbcdbc";
		System.out.println(sss1.indexOf("cdb",10));//
		//最后一次
		System.out.println(sss1.lastIndexOf("cdb",10));
		
		//返回规范化表示形式(不用记)
		System.out.println("qwe".intern());//qwe
		//是否为空字符串
		System.out.println("".isEmpty());//true
		//字符串的长度    数组.length
		System.out.println("qwe".length());//3
		//替换
		String str1 = "qweqwq";
		System.out.println(str1.replace('q', '*'));//aweawa
		//拆分
		String url = "www_baidu_com";
		String[] s9 =url.split("_");
		System.out.println( s9[1] );
		//截取字符串
		String u = "abcDef";
		System.out.println(u.substring(1));//bcdef
		System.out.println(u.substring(1,3));//bc
		//转换成字符数组
		char[]  ccc= u.toCharArray();//{'a','b','c','d','e','f'}
		//不用遍历查看数组中的元素
		System.out.println(Arrays.toString(ccc));
		//转 大小写
		System.out.println(u.toLowerCase());//abcdef
		System.out.println(u.toUpperCase());//ABCDEF
		//去首尾空格
		System.out.println(" a b c ".trim());//a b c
		int a = 10;
		System.out.println(String.valueOf(a) + 5);//105
		
	}

}

18.1.1 重写equals() 和 tostring() 方法

package day0218.c;
/*
 作业一:
创建一个Student类,
该有String类型的学号stuNo,
String类型的姓名,
要求将该类所有的成员变量进行封装,
并且提供公共的getter和setter方法,
重写equals方法,只要学生的学号相同即返回true,
重写toString()方法,
toString方法返回值类似”姓名:张三  学号:201301 ”
 */
public class Student {
		private String stuNo;
		private String name;
		
		@Override
		public String toString() {
			return "姓名:"+this.name+" 学号:"+this.stuNo;
		}
		
		@Override
		public boolean equals(Object obj) {
			if(obj instanceof Student) {
				Student s = (Student)obj;
				if(this.stuNo.equals(s.getStuNo())) {
					return true;
				}
			}			
			return false;
		}
		
		
		public String getStuNo() {
			return stuNo;
		}
		public void setStuNo(String stuNo) {
			this.stuNo = stuNo;
		}
		public String getName() {
			return name;
		}
		public void setName(String name) {
			this.name = name;
		}
		
}


18.1.2 敏感词替换replaces(old,new)

package day0218.c;
/*
 *  String  是一个 不可改变的 字符串
 */
public class MinGanCi {

	public static void main(String[] args) {
		/*
		 * 作业二:
			编写敏感词过滤程序 
 			在网络程序中,如聊天室、聊天软件等,
 			经常需要对一些用户所提交的聊天内容中的敏感性词语进行过滤。
 			如“性”、“色情”、“爆炸”、“恐怖”、“枪”等,
 			这些都不可以在网上进行传播,
 			需要过滤掉或者用其他词语替换掉。
		 */
		String[] mgc = {"暴力","性","爆炸","恐怖","枪","色情","用户所提交的"};
	
		String message = "编写敏感词过滤程序\r\n" + 
				" 			在网络程序中,如聊天室、聊天软件等,\r\n" + 
				" 			经常需要对一些用户所提交的聊天内容中的敏感性词语进行过滤。\r\n" + 
				" 			如“性”、“色  情”、“爆   炸”、“恐怖”、“枪”等,\r\n" + 
				" 			这些都不可以在网上进行传播," ;
	
		//去空格
		message = message.replace(" ", "");	
		//替换敏感词
		for (int i = 0; i < mgc.length; i++) {
			String xx = "";
			//遍历 敏感词  拼接 多少个星星
			for (int j = 0; j < mgc[i].length(); j++) {
				xx = xx + "*";
			}
			message = message.replace(mgc[i], xx);
			
		}

		System.out.println(message);
		
	}

}

18.1.3 正则表达式 .mathes()

package day0218.c;

public class ZhuCe {

	public static void main(String[] args) {
		/*
		  在注册时通常要验证用户名和密码是否合法,
		 运用学习过的知识完成如下操作:
			用户名长度大于等于6位,
				必须包含数字和英文字母
			密码长度大于等于8位,
				必须包含特殊符合_或者$,英文字母以及数字
		以上两个条件同时成立注册才能成功。
		 */
		String name="4A";
		String pass="";
		if(name.length()>=6 && pass.length()>=8) {
			if(		  name.matches(".*[a-zA-Z]+.*") 
					&& name.matches(".*[0-9]+.*") 
					&& pass.matches(".*[a-zA-Z]+.*") 
					&& pass.matches(".*[0-9]+.*") 
					&& pass.matches(".*[_$]+.*")
					) {
				System.out.println("注册成功");
			}else {
				System.out.println("账号或密码不符合规则");
			}
			
		}else {
			System.out.println("账号或密码不符合规则");
		}	
	
		//用来判断是否 符合 某种规则  符合返回true 
		//参数  就是书写的某种 规则  叫 正则表达式
		/*
		 *  正则表达式
		 *  	是由 一堆特殊 符号 组成的 字符串
		 *  	代表了 某种规则
		 *  ^  $
		 *  []  \d  \D  \w \W
		 *  [^]
		 *  ?  +  *   {}
		 *  
		 *  \  转义字符
		 */
	
		/*
		String name = "aaaabcac";  
		String regex = "^[abc]{8,12}$";
		System.out.println( name.matches(regex) );
		*/
				
		/*String name = "qweqwe";
		boolean b1 = false; //标记是否有数字
		boolean b2 = false;//标记是否有字母
		for (int i = 0; i < name.length(); i++) {
			if(name.charAt(i)>='0'  && name.charAt(i)<='9') {
				b1 = true;
				System.out.println("有数字");
				break;
			}
		}
		for (int i = 0; i < name.length(); i++) {
			if(name.charAt(i)>='a'  && name.charAt(i)<='z') {
				b2 = true;
				System.out.println("有字母");
				break;
			}
		}
		
		if(b1 && b2) {
			System.out.println("名字符合");
		}
*/
	}

}

package day0218.c;

public class ZhuCe {

	public static void main(String[] args) {
		/*
		  在注册时通常要验证用户名和密码是否合法,
		 运用学习过的知识完成如下操作:
			用户名长度大于等于6位,
				必须包含数字和英文字母
			密码长度大于等于8位,
				必须包含特殊符合_或者$,英文字母以及数字
		以上两个条件同时成立注册才能成功。
		 */
		String name="4A";
		String pass="";
		if(name.length()>=6 && pass.length()>=8) {
			if(		  name.matches(".*[a-zA-Z]+.*") 
					&& name.matches(".*[0-9]+.*") 
					&& pass.matches(".*[a-zA-Z]+.*") 
					&& pass.matches(".*[0-9]+.*") 
					&& pass.matches(".*[_$]+.*")
					) {
				System.out.println("注册成功");
			}else {
				System.out.println("账号或密码不符合规则");
			}
			
		}else {
			System.out.println("账号或密码不符合规则");
		}
			
	
		//用来判断是否 符合 某种规则  符合返回true 
		//参数  就是书写的某种 规则  叫 正则表达式
		/*
		 *  正则表达式
		 *  	是由 一堆特殊 符号 组成的 字符串
		 *  	代表了 某种规则
		 *  ^  $
		 *  []  \d  \D  \w \W
		 *  [^]
		 *  ?  +  *   {}
		 *  
		 *  \  转义字符
		 */
	
		/*
		String name = "aaaabcac";  
		String regex = "^[abc]{8,12}$";
		System.out.println( name.matches(regex) );
		*/
		
		
		
		
		
		/*String name = "qweqwe";
		boolean b1 = false; //标记是否有数字
		boolean b2 = false;//标记是否有字母
		for (int i = 0; i < name.length(); i++) {
			if(name.charAt(i)>='0'  && name.charAt(i)<='9') {
				b1 = true;
				System.out.println("有数字");
				break;
			}
		}
		for (int i = 0; i < name.length(); i++) {
			if(name.charAt(i)>='a'  && name.charAt(i)<='z') {
				b2 = true;
				System.out.println("有字母");
				break;
			}
		}
		
		if(b1 && b2) {
			System.out.println("名字符合");
		}
*/
	}

}

18.2 Object类常用的方法

1. Object 类的方法

所有类的 基类

clone() 克隆

equals(Object o) 用来比较对象 是否"相等"

hashcode() 返回哈希码值 随机的数值 是对象的唯一标识

toString() 返回对象地址的 字符串表示形式

当我们直接打印对象的时候 默认调用toString()

2. ==和equlas()的区别:

== 既可以用来比较对象 也可以用来比较基本值

equlas 只能比较对象

  1. 在Object类中的equlas方法就是用==号实现的

用来比较对象是否位同一个对象

​ hashCode(); 哈希码值

​ toString(); 包名+类名@ab124e

​ equals(Object obj); this == obj

  • String

  • toString() 当我们打印对象的时候 其实就是在执行此方法

    用来重写的

    当打印对象的时候 不想打印地址 就需要重写

  • “abc” 此字符串 既是常量 又是 对象

    静态域和常量池中的内容

    都是 最先 加载 并且 只加载一次

  • hashCode();

    理论上是 不同的对象 拥有 不同的 哈希值

    但 对象不同 有可能 其 哈希值 相同

  • == 和 equals 区别

    == 既可以比较 基本值 也可以比较对象

    比较对象 判断的是 是否为同一个 对象

    • equals
      • 是Object类中的方法
      • 用来比较对象是否相同 不能比较基本值
      • 在Object中 equals就是用 == 号实现的 与 ==作用相同
      • 在String类中 equals被重写 用来比较 字符串的 字面值 是否相同

    一般情况下 重写了equals()也要把hashCode()一起重写

    package day0217.a;
    /*
     * Object
     * 		hashCode();
     * 		toString(); 包名+类名@ab124e
     * 		equals(Object obj);   this == obj
     * String
     * 
     * 	toString() 当我们打印对象的时候  其实就是在执行此方法
     * 				用来重写的  
     * 				当打印对象的时候  不想打印地址 就需要重写
     * 
     * 	"abc"  此字符串  既是常量  又是 对象
     * 			静态域和常量池中的内容
     * 			都是 最先 加载  并且 只加载一次
     * 
     * 	hashCode();
     * 			理论上是  不同的对象 拥有 不同的 哈希值
     * 			但 对象不同  有可能  其 哈希值  相同
     * 
     * 	== 和 equals 区别
     * 		==  既可以比较 基本值  也可以比较对象
     * 			比较对象 判断的是  是否为同一个  对象
     * 		equals
     * 			是Object类中的方法
     * 			用来比较对象是否相同  不能比较基本值
     * 			在Object中  equals就是用 == 号实现的  与 ==作用相同
     * 			在String类中 equals被重写  用来比较  字符串的 字面值 是否相同
     	
     	一般情况下  重写了equals()也要把hashCode()一起重写
     */
    
    class Dog{
    	String name;
    	int age;
    	@Override
    	public int hashCode() {
    		return this.name.hashCode()+this.age;
    	}
    	
    	@Override
    	public String toString() {
    		return "Dog  name="+this.name+" age="+this.age;
    	}
    	//比较两条狗是否为 同一个的话
    	@Override
    	public boolean equals(Object obj) {
    		if(this == obj) {
    			return  true;
    		}
    		if(obj instanceof Dog) {
    			Dog oDog = (Dog)obj; 
    			if(this.age == oDog.age) {
    				if(this.name.equals(oDog.name)) {
    					return true;
    				}
    			}
    		}
    		return false;
    	}	
    }
    
    public class TestString1{
    	public static void main(String[] args) {
    	
    		
    		
    		double[] a = new double[5];
    		System.out.println(a);// [D@7852e922
    		
    		Object o = new Object();
    		System.out.println(o);//java.lang.Object@4e25154f
    		
    		String s = new String("qwe");
    		System.out.println(s);
    		System.out.println(s.toString());//qwe
    	
    		//char的包装类类型
    		Character ch = new Character('q');
    		System.out.println(ch);//q
    		
    		Dog d = new Dog();
    		d.name="大黄";
    		d.age = 18;
    		System.out.println(d);
    		System.out.println("===========hashCode()================");
    		//此处创建了3个新对象
    		String s1 = new String("abc");
    		String s2 = new String("abc");
    		System.out.println("abc".hashCode());//96354
    		System.out.println(s1.hashCode());//96354
    		System.out.println(s2.hashCode());//96354
    		
    		System.out.println(s1 == s2); // false
    		System.out.println(s1.equals(s1));// true
    
    		
    		Dog d1 = new Dog();
    		Dog d2 = new Dog();
    		d1.name="qwe";
    		d1.age=3;
    		d2.name="qwe";
    		d2.age=3;
    		System.out.println(d1.hashCode());
    		System.out.println(d2.hashCode());
    		System.out.println(d1.equals(d2));
    		System.out.println(d1);
    		System.out.println(d2);
    		System.out.println(d1 == d2);
    		
    		System.out.println("===========常见的String错误==============");
    		String  a1 = "abc";
    		String  a2 = "abc";
    		System.out.println(a1 == a2); //true
    		System.out.println(a1.equals(a2));//true
    		
    		String  aa1 = new String("abc");
    		String  aa2 = new String("abc");
    		System.out.println(aa1 == aa2); //false
    		System.out.println(aa1.equals(aa2));//true
    		String b1 = "ab" + "cd";
    		String b2 = "abcd";
    		System.out.println(b1 == b2);//true
    		System.out.println(b1.equals(b2));//true
    	
    		String bb0 = "ab";
    		String bb1 = bb0 + "cd";
    		String bb2 = "abcd";
    		System.out.println(bb1 == bb2);//false
    		System.out.println(bb1.equals(bb2));//true
    		
    	}
    }
    
    

18.3 system类常用的方法

System 系统类
属性:
in new Scanner(System.in)
out System.out.println();
err System.err.println();
方法
退出 参数位0 代表正常 退出

			System.exit(1);
			System.currentTimeMillis() 从1970.01.01 0:0:0 000 到现在所经过的毫秒数
			//垃圾回收的方法
		 	System.gc();
		 	Runtime.getRuntime().gc();

Math 数学类
E
PI

package day0217.a;
/*
  System 系统类
  		属性:
  				in        new Scanner(System.in)
  				out		  System.out.println();	
  				err		  System.err.println();	
  		方法		
 			退出  参数位0 代表正常 退出
				System.exit(1);
				System.currentTimeMillis() 从1970.01.01 0:0:0 000 到现在所经过的毫秒数
 				//垃圾回收的方法
			 	System.gc();
			 	Runtime.getRuntime().gc();
  
  Math   数学类
  			E
  			PI
  
 */
public class TestSystemAndMath {

	public static void main(String[] args) {
			System.out.println("程序开始");
			//System.exit(0);
			//System.out.println( System.currentTimeMillis()/1000/60/60/24/365 );
			
			long begin = System.currentTimeMillis();
			for (int i = 0; i < 10000; i++) {
				System.out.println(i);
			}
			long end = System.currentTimeMillis();
			System.out.println("循环一万次需要"+(end - begin));
			
			//垃圾回收的方法
			 System.gc();
			 Runtime.getRuntime().gc();	
			 
			 System.out.println("============Math==============");
			 System.out.println(Math.E);
			 System.out.println(Math.PI);
			// [0,1) 的随机  小数
			 System.out.println( Math.random());
			 System.out.println(Math.round(-3.5));
			 System.out.println(Math.floor(-3.6));
			 System.out.println(Math.ceil(3.6));
			 
			System.out.println("程序结束");
	}

}

18.4 StringBuffer 和 StringBuilder 类

当new StringBuffer()或者new StringBuilder()时,就会生成 16 个容量的字符缓冲区,当创建对象传值时,容量为值的长度加十六。

StringBuffer和 StringBuilder 上的主要操作:

1.容量数值:capacity() 返回int类型的容量数值

2.追加: append() ,每调用一次append方法,当容量超出,就会进行一次扩容,执行

​ (容量数值 + 1)* 2 = 容量数值 * 2 + 2 = 扩容后的容量数值

StringBuffer sbf = new StringBuffer("abcdefg");//初始值
   	//StringBuilder sbl = new StringBuilder();		
   	//返回当前容量     初始容量16(缓冲区16)+初始值个数7个=23
   	System.out.println(sbf.capacity()); //16+7=23
   	//追加字符串
   	sbf.append("abcdeabcdeabcdeabcde"); //追加20个
   	System.out.println(sbf);//此处的sbf.tostring为重写后的
   	System.out.println(sbf.capacity());  //23*2+2 = (23+1)*2=48

3.删除:delete(int start, int end) 删除 索引从开始到结束索引处的值

        sbf.delete(0, 10); //删除索引从0到10的值
		System.out.println(sbf); 

4.reverse () 颠倒

5.replace () 替换

package day0219.a;
/*
 * String 			不可变的字符串
 * StringBuffer		可变字符串   线程安全的    执行效率低
 * StringBuilder    可变字符串   线程不安全的  执行效率第高
 * 	都是用来处理字符串
 * 	当追加的字符串 超过了 初始容量16  
 * 	每调用一次append()就会进行一次扩容  16*2+2 = 34  当超出34个字符之后 按照实际的来
 */
public class TestStringBuffer {

	public static void main(String[] args) {
		StringBuffer sbf = new StringBuffer("qwe");
		StringBuilder sb = new StringBuilder("qwe");
		long begin = System.currentTimeMillis();
		for (int i = 0; i < 10000000; i++) {
			sb.append("qwe");
		}
		long end = System.currentTimeMillis();
		System.out.println(end - begin);
		
	/*	StringBuffer sb = new StringBuffer("qwe");	
		System.out.println(sb.hashCode());//2018699554
		//返回当前的容量了 初始容量16
		System.out.println(sb.capacity());//16
		//追加字符串
		sb.append("abcdeabcdea");
		System.out.println(sb);//a
		System.out.println(sb.capacity());//34
		System.out.println(sb.hashCode());//2018699554
		
		sb.delete(0, 3);
		System.out.println(sb);
	*/
		/*
		 * //可变字符串和 不可变字符串的区别
		String s = "qwe";
		String b = s.replace("q", "a");
		System.out.println(s);//qwe
		System.out.println(b);//awe
		StringBuffer sb = new StringBuffer("qwe");
		StringBuffer bc = sb.append("abc");
		System.out.println(sb);//qweabc
		System.out.println(sb == bc);
		System.out.println(sb.equals(bc));
		*/		
		/*
		StringBuffer sb = new StringBuffer("  qwe  ");
		sb.insert(1, "abc  ");
		System.out.println(sb);
		System.out.println(sb.reverse());
		System.out.println(sb.capacity());
		sb.trimToSize();
		System.out.println(sb.capacity());
		*/
	}

}

19.抽象类 和 接口

普通类 :构造器、属性、方法
抽象类 :被 abstract 修饰的类 就叫做抽象类
构造器、属性、方法
抽象方法 被abstract修饰的方法 并且没有 方法体
抽象类 不能被 实例化 可以new其子类对象 调用方法
​ 一个普通的类 继承 抽象类 必须要重写 抽象类中的 抽象方法

​ public abstract class TestCXL {

​ abstract void mm() ; }

接口: 更加抽象的 抽象类
用interface定义
不能写属性 方法 和 构造器
可以写抽象方法 和 静态常量

类 继承 (extends) 类 (单继承)

类 实现 (implements) 接口 (多实现)

接口 继承 (extends) 接口 (多继承) 打破了java中单继承的 缺点

package day0221.a;
/*
  普通类
   	构造器
   	属性
   	方法
   抽象类   被 abstract 修饰的类 就叫做抽象类
   	构造器
   	属性
   	方法
   	抽象方法   被abstract修饰的方法  并且没有 方法体
   	抽象类 不能被  实例化  可以new其子类对象 调用方法
  一个普通的类  继承 抽象类  必须要重写 抽象类中的 抽象方法 	
  
  接口: 更加抽象的 抽象类 
  		用interface定义
  		不能写属性   方法 和 构造器
		
 		可以写抽象方法 和  静态常量
  
  		interface BBB{
   		// public static final double PI = 3.14; 
				double PI = 3.14;
			// public abstract void mm();
				void mm();
		}
		
	类  继承 (extends)    类     (单继承)
	类  实现  (implements)接口  (多实现)
	接口   继承(extends)   接口  (多继承)  打破了java中单继承的 缺点
	
	jdk1.8之后
		接口中可以有 静态方法 和 默认方法:
		public static void kk() {
		
		}
		public  default void ll() {
		
		}
  
 */
public abstract class TestCXL {
	//abstract void mm() ;
}
interface BBB extends CCC,DDD{
	double PI = 3.14;
	void mm();
}
interface CCC{
	//jdk1.8之后  可以有方法体的 两种方法
	public static void kk() {
		
	}
	public  default void ll() {
		
	}
	
	void nn();
}
interface DDD{
	void nn();
}
class AAA extends TestCXL implements BBB , CCC{
	@Override
	public void nn() {
	
	}
	@Override
	public void mm() {
		// TODO Auto-generated method stub		
	}	
}

20.Java.util包

20.1 Date类

java.util 包下的Date类

Date d = new Date();
		System.out.println(d);
		Date d1 = new Date(2000);//2000毫秒=2秒
		System.out.println(d1);
		System.out.println(d1.after(d));
		System.out.println(d.getDate());//21
		System.out.println(d.getDay());//1
		System.out.println(d.getHours());//10
		System.out.println(d.getMinutes());//21
		System.out.println(d.getMonth());//1
		
		System.out.println(d.getTime());
		System.out.println(System.currentTimeMillis());

20.3 Calendar 日历类

(抽象类 不能new) GregorianCalendar 是 Calendar 子类

GregorianCalendar c = new GregorianCalendar();

	c.setTime(new Date());
	        System.out.println(c.get(Calendar.YEAR));
System.out.println(c.get(c.MONTH)+1);

20.3 Format 格式化类

package day0221.a;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/*
 * Format	格式化类  (抽象)
 * 		NumberFormat  数字格式化类(抽象)
 * 		DateFormat    日期格式化类(抽象)
 * 			SimpleDateFormat  简单的日期格式化类	
 * 							 可以将Date类型的日期  格式化成 想要的字符串
 * 							将代表日期的字符串  解析成  Date类型
 */
public class TestDateFormat {
	public static void main(String[] args) throws ParseException {
		System.out.println("=============格式化================");
		//Date类型的日期  格式化成 想要的字符串格式
		Date d =  new Date();
		//Mon Feb 21 11:39:04 CST 2022
		System.out.println(d);
		//将 上面的日期格式化成   2022年2月21日 11:39:04
		SimpleDateFormat  sdf = new SimpleDateFormat("MM/dd yyyy HH:mm:ss a");
		//格式化
		String str = sdf.format(d);
		System.out.println(str);
		System.out.println("=============解析================");
		//代表日期的字符串  解析成  Date类型
		String  date = "1987-06月3日";
		SimpleDateFormat  sdf1 = new SimpleDateFormat("yyyy-MM月dd日");
		//解析的方法
		Date  da = sdf1.parse(date);
		System.out.println(da);
		
	}

}

20.1 异常

异常 只是程序在执行过程中 发生的不正常的情况 不是错误

Throwable 可抛出的类
Error 错误
Exception 异常
编译期异常 Exception的所有子类
运行期异常 RuntimeException 的子类

编译期异常 在编译代码的时候 就会报异常
需要处理
运行期异常 在运行的时候 出现的异常 可以不处理

异常的处理方式:
throws 抛出 不管
try-catch 捕获

package day0222;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/*
   异常  只是程序在执行过程中 发生的不正常的情况  不是错误
   
   Throwable  可抛出的类
   	Error		错误
   	Exception	异常  
   		编译期异常 Exception的所有子类
   		运行期异常 RuntimeException 的子类
   
   编译期异常 在编译代码的时候 就会报异常
   		  需要处理
   运行期异常 在运行的时候 出现的异常   可以不处理	
   
   异常的处理方式:
   	throws		抛出    不管
   	try-catch   捕获
   	
 */
public class Exceptiontest {
	public static void main(String[] args){
		Student s = new Student();
		s.setAge(-14);
		int[] arr = new int[4];
		System.out.println( arr[2] );
		
		
		String  date = "1987*06月3日";
		SimpleDateFormat  sdf1 = new SimpleDateFormat("yyyy-MM月dd日");
		//解析的方法
		try {
			Date  da = sdf1.parse(date);
		}catch(ParseException q) {
			q.printStackTrace();
			//System.out.println("有异常了");
		}
		
		
		System.out.println("程序结束");
	}
}
class Student{
	private int age;
	public int getAge() {
		return age;
	}
	public void setAge(int age) {	
			this.age = age;
		
	}
	
}

常见的运行期异常:出现了运行期异常 虚拟机就停止了
可以避免的 所以可以不进行 处理
RuntimeException
java.lang.ArithmeticException 算数(除0)异常
IndexOutOfBoundsException 角标越界
java.lang.ArrayIndexOutOfBoundsException 数组角标越界
java.lang.StringIndexOutOfBoundsException 字符串角标越界
java.util.InputMismatchException 输入不匹配异常
java.lang.ClassCastException 类型转换异常 (向下转型)
java.lang.IllegalArgumentException 非法参数异常
java.lang.NullPointerException 空指针异常
Exception 子类都是编译器异常:

package day0222;

import java.text.SimpleDateFormat;
import java.util.Scanner;

/*
     常见的运行期异常:出现了运行期异常  虚拟机就停止了
  		可以避免的  所以可以不进行 处理
  	RuntimeException
  		java.lang.ArithmeticException  算数(除0)异常
  		IndexOutOfBoundsException		角标越界
  			java.lang.ArrayIndexOutOfBoundsException 数组角标越界
  			java.lang.StringIndexOutOfBoundsException 字符串角标越界
  		java.util.InputMismatchException  	输入不匹配异常
  		java.lang.ClassCastException    	类型转换异常 (向下转型)
 		java.lang.IllegalArgumentException  非法参数异常
 		java.lang.NullPointerException		空指针异常
   Exception 子类都是编译器异常:
  *
  */
public class TestException {

	public static void main(String[] args) {
			System.out.println("程序开始");
			/*int i = 10;
			Scanner sc = new Scanner(System.in);
			int a = sc.nextInt();
			//避免运行期异常
			if(a != 0) {
				System.out.println(i/a);
			}*/
			
			/*int[] arr = new int[4];
			System.out.println(arr[4]);*/
			
			/*String s = "qwe";
			System.out.println(s.substring(4));*/
			/*
			Scanner sc = new Scanner(System.in);
			int a = sc.nextInt();
			*/
			/*
			Object o = new Object();
			TestException te = (TestException)o;
			*/
			/*
			SimpleDateFormat sdf = new SimpleDateFormat("qweqew");
			*/
			/*
			Object o = null;
			System.out.println(o.hashCode());
			*/		
			System.out.println("程序结束");
	}

}
package day0225.b;
/**
 * 作为一个  编译期异常
 *
 */
public class AgeBNDaYu150 extends Exception{
	public AgeBNDaYu150() {
		
	}
	public AgeBNDaYu150(String message) {
		super(message);
	}
}

package day0225.b;
/**
 * 自定义一个异常  只要继承  异常就可以了
 * 作为 运行期异常  需要 继承 RuntimeException
 *
 */
public class AgeCanNotSmaller0Exception extends RuntimeException{

	public AgeCanNotSmaller0Exception() {
		
	}
	public AgeCanNotSmaller0Exception(String s) {
		super(s);
	}
}

package day0225.b;
/*
 * 1. try-catch的执行过程
 * 		1.想让程序不停止  必须 被catch捕获到 如果捕获不到  就由虚拟机来处理
 * 			虚拟机的处理方式就是程序停止 下面的代码 不再执行
 * 		2.jdk1.7之后的新语法
 * 		3.finally 与 try连用  在JVM结束之前 执行
 * 			无论是否有 异常情况发生  都会执行  finally块中的代码
 * 		  System.exit(0);  finally块不执行
 */
public class KuoZhanException {

	public static void main(String[] args) {
		
		//try - catch - finally  还可以这样写
		/*
		try {
			
		}finally{
			
		}
		
		try {
			
		}catch(Exception e) {
			
		}
		*/
	
		System.out.println("程序开始");
		/*
			try {
				System.out.println("===========");
				System.out.println(10/0);
				System.out.println("*************");
				Class.forName("java.lang.Object");
				System.out.println("+++++++++++++");
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			} catch (ArithmeticException e) {
				e.printStackTrace();
			} catch (Exception e) {
				e.printStackTrace();
			}
			*/
		/*
		//jdk1.7
		try {
			System.out.println("===========");
			System.out.println(10/0);
			System.out.println("*************");
			Class.forName("java.lang.Object");
			System.out.println("+++++++++++++");
		} catch (ClassNotFoundException | ArithmeticException e ) {
			e.printStackTrace();
		} 
		*/
		// finally
		try {
			System.out.println("===========");
			System.out.println(10/2);
			System.out.println("*************");
			Class.forName("java.lang.Object");
			System.out.println("+++++++++++++");
			//return;//结束方法
			System.exit(0);//退出虚拟机
		
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (ArithmeticException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		} finally{
			System.out.println("我奏是要执行");
		}
		
			System.out.println("程序结束");
	}

}

21集合

*List , Set, Map都是接口,前两个继承至Collection接口,Map为独立接口
*Set下有HashSet,LinkedHashSet,TreeSet
*List下有ArrayList,Vector,LinkedList
*Map下有Hashtable,LinkedHashMap,HashMap,TreeMap
*Collection接口下还有个Queue接口,有PriorityQueue类

Collection
List AbstractList 有序 有索引 元素可重复
有序:元素添加的顺序 和存储的顺序一致
有索引:可以通过索引 进行 CRUD的操作
元素可重复 :
ArrayList 底层实现 是一个大小可变的数组

​ Vector 10 1 * 2
LinkedList
Stack

SetSet	无序无索引 元素不可重复
	HashSet  如果元素重复 存不进去
			 初始容量 16   0.75   * 2
			 底层实现是 HashMap的键
	                使用hash表(数组)存储元素

	TreeSet

​ 分为自然排序(无参构造)和比较器排序(有参构造),自然排序要 求元素必须实现Compareable接口,并重写里面的compareTo()方法

集合中存储的 都是 对象 不能存储 基本类型的值
jdk1.5之后 基本数据类型 和 包装类类型可以自动转换
int ----> Integer 自动装箱
Integer ----> int 自动拆箱

Collection 接口的接口 对象的集合(单列集合)
├——-List 接口:元素按进入先后有序保存,可重复
│————├ LinkedList 接口实现类, 链表, 插入删除, 没有同步, 线程不安全
│————├ ArrayList 接口实现类, 数组, 随机访问, 没有同步, 线程不安全
│—————-└ Vector 接口实现类 数组, 同步, 线程安全
│ ———————-└ Stack 是Vector类的实现类
└——-Set 接口: 仅接收一次,不可重复,并做内部排序
├—————-└HashSet 使用hash表(数组)存储元素
│————————└ LinkedHashSet 链表维护元素的插入次序
└ —————-TreeSet 底层实现为二叉树,元素排好序

Map 接口 键值对的集合 (双列集合)
├———Hashtable 接口实现类, 同步, 线程安全
├———HashMap 接口实现类 ,没有同步, 线程不安全-
│—————–├ LinkedHashMap 双向链表和哈希表实现
│—————–└ WeakHashMap
├ ——–TreeMap 红黑树对所有的key进行排序
└———IdentifyHashMap
————————————————
版权声明:本文为CSDN博主「phial03」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/feiyanaffection/article/details/81394745

21.1 ArrayList

(1)ArrayList:底层数据结构是数组,查询快,增删慢,线程不安全,效率高,可以存储重复元素
(2)LinkedList 底层数据结构是链表,查询慢,增删快,线程不安全,效率高,可以存储重复元素

(3)Vector:底层数据结构是数组,查询快,增删慢,线程安全,效率低,可以存储重复元素

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x6WzrWgE-1648275882438)(images\20180803201736883.png)]

Set和List对比

Set:检索元素效率低下,删除和插入效率高,插入和删除不会引起元素位置改变。
List:和数组类似,List可以动态增长,查找元素效率高,插入删除元素效率低,因为会引起其他元素位置改变。


add() 添加

clear() 移除此列表中的所有元素
contains() 判断集合中是否包含某元素
remove 删除
set(索引,要修改后的元素) 修改
size() 列表中的元素数
get() 通过索引获取元素
indexOf() 通过元素寻找第一次出现的位置的索引
isEmpty() 判断该集合是否为空,如果此列表中没有元素,则返回 true
lastIndexOf(Object o) 返回此列表中最后一次出现的指定元素的索引,或如果此 列表不包含索引,则返回 -1
此 ArrayList 实例的容量调整为列表的当前大小

package day0228.b;

import java.util.ArrayList;
import java.util.Iterator;

public class ArrayList1 {

	public static void main(String[] args) {
	//创建一个ArrayList()对象
		ArrayList al1 = new ArrayList();  //默认初始容量为10 
		ArrayList al2 = new ArrayList(20);  //自定义int容量为20
		//ArrayList al3 = new ArrayList(al1);  //
		//System.out.println(al3);
		
	//add()  添加
		al1.add("不迷信哇");   //添加string类型的值
		al1.add(1,"芜湖");   //在索引为1的位置添加string类型的值
	    //al1.add(5,"aaa");  //java.lang.IndexOutOfBoundsException 角标越界异常,虽然有容量为10,但不能超出索引
		al1.add(2,"aaa");    //在索引为2的位置上添加String类型的"aaa"
		al1.add(3,66);       //在索引为3的位置上添加Integer类型的66
		al1.add(88);       //ArrayList中不能存基本数据类型的值,所以88为Integer包装类
		al1.add("嗷呜");
		al1.add("哒哒哒");
		al1.add("啦啦啦");
		al1.add(66);
		al1.add(4,"芜湖");
		System.out.println(al1);
	//clear() 移除此列表中的所有元素
	//contains() 判断集合中是否包含某元素
		System.out.println(al1.contains("芜湖"));
	//remove 删除
		al1.remove(1);  //删除索引为1的位置的数值
		System.out.println(al1.remove("芜湖"));  //移除此列表中首次出现的指定元素
		System.out.println(al1);  //在ArrayList中tostring被重写,返回的是一个类似数组的string字符串
	//set(索引,要修改后的元素) 修改
		al1.set(2, "我是被set()修改后的元素");
	//size() 列表中的元素数        类似于数组中的length
		System.out.println(al1.size());
		System.out.println(al1.toArray()); 
	//get() 通过索引获取元素
		System.out.println(al1.get(5));  //获取索引为5的位置的元素
	//indexOf()  通过元素寻找第一次出现的位置的索引
		al1.add("aaa");
		System.out.println(al1.indexOf("aaa"));  //获取"aaa"第一次出现的索引
	//isEmpty() 判断该集合是否为空,如果此列表中没有元素,则返回 true 
		System.out.println(al1.isEmpty());
	//lastIndexOf(Object o) 返回此列表中最后一次出现的指定元素的索引,或如果此列表不包含索引,则返回 -1
		System.out.println(al1.lastIndexOf("aaa"));
	//此 ArrayList 实例的容量调整为列表的当前大小
		al1.trimToSize();
		System.out.println(al1);  //在ArrayList中tostring被重写,返回的是一个类似数组的string字符串
		
		//1.遍历输出for
		for (int i = 0; i < al1.size(); i++) {
			System.out.print(al1.get(i)+"   ");
		}
		//2.foreach
		for (Object o : al1) {
			System.out.print(o+" ");
		}
		int[]  arr = {11,22,33,44};
		for(int  c : arr) {
			System.out.println(c);
		}
		
		//3.迭代器
		Iterator iterator = al1.iterator();
		while (iterator.hasNext()) {
			Object obj = iterator.next();
			System.out.println(obj);			
		}
	}

}

泛型

package day0228.b;

import java.util.ArrayList;
import java.util.Iterator;

public class ArrrayList2 {
   
	public static void main(String[] args) {
		//泛型:在集合中 泛型的作用是规定 集合中存储的 元素的类型
		//如果不写 默认Object类型
		
		ArrayList<Integer> arl1 = new ArrayList<Integer>();
		// <Integer> 中规定只能存储Integer类型的元素
		
		arl1.add(11);
		arl1.add(22);
		arl1.add(33);
		arl1.add(44);
		//arl1.add("55");  //报错
		//arl1.add(66.6);   //报错
		arl1.add((int) 66.6); //强转为int类型
		System.out.println(arl1); //toString()重写
		System.out.println(arl1.get(3)); //get()输出索引为3的元素
		
		//迭代器遍历
		Iterator<Integer> it = arl1.iterator();
		while(it.hasNext()){
			Integer s = it.next();
			System.out.print(s+"  ");
		}
		System.out.println();
		//foreach遍历
		for (Integer integer : arl1) {
			System.out.print(integer+"  ");
		}
		

	}

}

class Money<T> {      //<T>一般写在类名之后
	T[] m;
	//此处的参数 不知道是什么类型 传来什么类型就是什么类型
	T  my(T o){
		return o;
	}
}

自定义一个集合

package day0228.a;

import java.util.Arrays;

/**
 * 自定义一个集合
 *		
 */
public class MyList {
	public static void main(String[] args) {
		MyList my = new MyList();
		my.add("qwe");
		my.add(123);
		my.add("zxc");
		my.add("qwe");
		my.add(123);
		my.add("zxc");
		my.add("qwe");
		my.add(123);
		my.add("zxc");
		my.add("qwe");
		my.add("qwe");
		my.remove(1);
		my.set(0, 789789798);
		System.out.println(my);
		System.out.println(my.get(0));
	}
	
	
	@Override
	public String toString() {
		return Arrays.toString(obj);
	}
	
	Object[] obj = new Object[10];
	int index = 0;
	//增
	public void add(Object o) {
		if(index > 9) {
			kr() ;
		}
		obj[index] = o;
		index++;
	}
	//查
	public Object get(int index) {
		return obj[index];
	}
	//改
	public void set(int index,Object o) {
		obj[index] = o;
	}
	public void remove(int index) {
		Object[] newObj = new Object[obj.length-1];
		for (int i = 0; i < newObj.length; i++) {
			if(i < index) {
				newObj[i] = obj[i];
			}else if(i >= index){
				newObj[i] = obj[i+1];
			}
		}
		obj = newObj;
	}
	//扩容
	private void kr() {
		int newLength = obj.length + (obj.length >> 1);
		Object[] newObj = new Object[newLength];
		for (int i = 0; i < obj.length; i++) {
			newObj[i] = obj[i];
		}
		obj = newObj;
	}
}

21.2 Stack

是Vector的子类
栈集合 存储规则 先进后出(FILO)First In Last OutS

package day0301.b;

import java.util.Stack;

public class StackTest {

	public static void main(String[] args) {
		Stack<String> s = new Stack<String>();
		s.add("哒哒哒");
		s.add(1, "呜呜呜");
		s.add(0,"啦啦啦");
		System.out.println(s);
		s.set(1, "哈哈");                 //set()  修改索引为1的元素
		System.out.println(s);
		
		//堆栈    Stack 是Vector的子类
		//   栈集合	  存储规则 先进后出(FILO)First In  Last OutS
		
		System.out.println(s.empty());   //empty() 测试堆栈是否为空 
		System.out.println(s.peek());    //peek()  查看堆栈顶部的对象,但不从堆栈中移除它。
		System.out.println(s.pop());     //pop()  移除堆栈顶部的对象,并作为此函数的值返回该对象。
		System.out.println(s.push("我是push"));   //push()  把项压入堆栈顶部
		
		//push() 返回对象在堆栈中的位置,以 1 为基数。
		System.out.println(s.search("我是push"));    //search()
		System.out.println(s.search("哈哈"));    //search()
		System.out.println(s.search("啦啦啦"));    //search()
		System.out.println(s.search("???"));    //search()
		
		System.out.println(s);

	}

}

21.3 Vector

(1)ArrayList:底层数据结构是数组,查询快,增删慢,线程不安全,效率高,可以存储重复元素
(2)LinkedList 底层数据结构是链表,查询慢,增删快,线程不安全,效率高,可以存储重复元素
(3)Vector:底层数据结构是数组,查询快,增删慢,线程安全,效率低,可以存储重复元素

==============================================================

Vector 也实现了 List接口 底层实现 是可变数组

​ JDK1.0
​ 初始容量 10 加载因子 1
​ 初始容量 * 2 = 当前容量
​ 线程安全 效率低

package day0301.b;

import java.util.Vector;

public class VectorTest {

	public static void main(String[] args) {
		Vector<Integer> v  = new Vector<Integer>();
		v.add(11);
		v.add(1,22);
		v.add(33);
		v.add(44);
		//v.add("55");   报错:泛型定义为Integer ,只能写int类型的元素
		v.addElement(66);   
		//addElement()将指定的组件添加到此向量的末尾,将其大小增加 1。
		v.add(55);
		v.add(66);
		v.add(77);
		v.add(88);
		v.add(99);
		v.add(111);
		v.add(222);
		
		//capacity() 返回当前容量
		 /*ArrayList  底层实现  是可变数组
			  初始容量 10   加载因子  1
			  初始容量 * 1.5 = 当前容量
			 线程不同步(线程不安全)  效率高
			JDK1.2 
         Vector  也实现了 List接口  底层实现  是可变数组
			JDK1.0 
			初始容量 10 加载因子  1
		           初始容量 *  2 = 当前容量
			线程安全     效率低
		*/
		System.out.println(v.capacity());  //初始容量为10,当存储数量大于10,
		                                    //初始容量 *  2 = 当前容量
		System.out.println(v);
		
	//clear() 清除所有元素
		//v.clear();  
		
	//contains() 判断是否包含指定元素	
		System.out.println(v.contains(333));   //false 不包含
		System.out.println(v.contains(33));    //true  包含
	//elementAt()  与 
	//get()     作用相同 ,返回索引处的元素
		System.out.println(v.elementAt(3));   //返回索引处的元素
		System.out.println(v.get(3));         //返回索引处的元素
		
		//System.out.println("=======返回枚举==========");
	    //System.out.println(v.elements());	
		
		//System.out.println(v.capacity());
		//System.out.println(v);
      //遍历 返回枚举
		System.out.println("========返回枚举===========");
		Enumeration<String> en = v.elements();
		while(en.hasMoreElements()) {
			String str = en.nextElement();
			System.out.print(str+" ");
		}
		System.out.println("\n========迭代器===========");
		Iterator<String> it = v.iterator();
		while(it.hasNext()) {
			String str = it.next();
			System.out.print(str+" ");
		}
				
		v.firstElement() ;
		v.get(0);
			
		v.add(2, "zxc");
		v.insertElementAt("zxc", 2);
		
		v.lastElement();
		v.get(v.size()-1);
		
		System.out.println(v.capacity());
	}
}

21.4 LinkedList

(1)ArrayList:底层数据结构是数组,查询快,增删慢,线程不安全,效率高,可以存储重复元素
(2)LinkedList 底层数据结构是链表,查询慢,增删快,线程不安全,效率高,可以存储重复元素
(3)Vector:底层数据结构是数组,查询快,增删慢,线程安全,效率低,可以存储重复元素

==============================================================

LinkedList
可以完成首尾双向操作
底层实现是一个链表

package day0301.a;

import java.util.LinkedList;

/*
 * LinkedList
  		可以完成首尾双向操作
  		底层实现是一个链表
 */
public class TestLinkedList {

	public static void main(String[] args) {
		LinkedList  ll = new LinkedList();
		ll.add("qwe");
		ll.offer("qwe");
		
		ll.addFirst("asd");
		ll.offerFirst("asd");
		
		ll.addLast("zxc");
		ll.offerLast("asd");
			
		ll.peek();
		ll.peekFirst();
		ll.peekLast();
		
		ll.pop();//获取并移除顶部元素  statck
		ll.poll();
		ll.pollFirst();
		ll.pollLast();		
	}

}

21.5 HashSet

Set 无序无索引 元素不可重复
HashSet 如果元素重复 存不进去
初始容量 16 0.75 * 2
底层实现是 HashMap的键
根据hash值存储的顺序

1.HashSet底层数据结构采用哈希表实现,元素无序且唯一,线程不安全,效率高,可以存储null元素,元素的唯一性是靠所存储元素类型是否重写hashCode()和equals()方法来保证的,如果没有重写这两个方法,则无法保证元素的唯一性。

**2.**HashSet采用哈希算法,底层用数组存储数据。默认初始化容量16,加载因子0.75

package day0302.b;

import java.util.HashSet;

public class HashSetTest {

	public static void main(String[] args) {
		HashSet<Dog> hashset =  new HashSet<Dog>();
		//new HashSet<Dog>() 新建HashSet对象 定义泛型类型为<Dog>
		
		Dog dog1 = new Dog("泰迪",1,"棕色"); //新建对象,给对象赋值
		Dog dog2 = new Dog("萨摩耶",2,"白色"); 
		Dog dog3 = new Dog("金毛",3,"黄色");
		Dog dog4 = new Dog("牧羊犬",3,"黑白花色");
		Dog dog5 = new Dog("牧羊犬",3,"黑白花色");
		
		hashset.add(dog1);  //当使用add的时候就进行了排序
		hashset.add(dog2);
		hashset.add(dog3);
		hashset.add(dog4);
		hashset.add(dog5); 
		
		System.out.print(hashset);  //toString重写
		System.out.println();
		
		System.out.println(dog4.equals(dog5)); //equals重写
		
		System.out.println(dog4.hashCode());//hashCode重写
		System.out.println(dog5.hashCode());
	}

}

package day0302.b;

import com.sun.org.apache.regexp.internal.recompile;

public class Dog {
	String name;
	int age;
	String color;
	
	public Dog() {
		// TODO Auto-generated constructor stub
	}
	public Dog(String name,int age,String color) {
		this.name = name; 
		this.age = age; 
		this.color = color; 
	}
	
	@Override
	public String toString() {
		
		return name+"今年"+age+"岁,"+"这是一只"+color+"的狗\n";
	}
	
	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj instanceof Dog) {
			Dog dog = (Dog) obj;
			if (dog.age == this.age && dog.name == this.name && this.color == dog.color) {
				return true;
			}
			return false;
		}
		
		return false;
	}
	
	@Override
	public int hashCode() {
		// TODO Auto-generated method stub
		return this.name.hashCode()+age+this.color.hashCode();
	}

}

21.6 TreeSet

TreeSet 有自然存储顺序的集合
自然的比较顺序
存储元素的时候
是根据 Comparable中的 compareTo()进行比较存储的顺序的
compareTo() 返回 负数
TreeSet在存储对象的时候 要求对象必须要有一个自然顺序
如何有自然顺序:
1.让类 实现Comparable接口
重写compareTo()方法
当添加元素的时候
ts.add(对象1) 对象1是 compareTo()方法中的 this
对象1是 compareTo()方法中的 o
ts.add(对象2)
对象2是 compareTo()方法中的 this
对象1是 compareTo()方法中的 o
ts.add(对象3)
对象3是 compareTo()方法中的 this
对象1是 compareTo()方法中的 o
对象2是 compareTo()方法中的 o

2.另写一个类 作为 比较器
implements Comparator接口
重写compare()

=======================================================

  1. TreeSet底层数据结构采用二叉树来实现,元素唯一且已经排好序;
  2. 唯一性同样需要重写hashCode和equals()方法,二叉树结构保证了元素的有序性。
  3. 根据构造方法不同,分为自然排序(无参构造)和比较器排序(有参构造),自然排序要求元素必须实现Compareable接口,并重写里面的compareTo()方法,元素通过比较返回的int值来判断排序序列,返回0说明两个对象相同,不需要存储;比较器排需要在TreeSet初始化是时候传入一个实现Comparator接口的比较器对象,或者采用匿名内部类的方式new一个Comparator对象,重写里面的compare()方法

————————————————

1.自然排序

自然排序要求元素必须实现Compareable接口,并重写里面的compareTo()方法,元素通过比较返回的int值来判断排序序列,返回0说明两个对象相同,不需要存储

package day0302.a;

import java.util.TreeSet;

import javax.sound.midi.Soundbank;

/**
  TreeSet  有自然存储顺序的集合
  			自然的比较顺序
 			存储元素的时候  
 			是根据 Comparable中的 compareTo()进行比较存储的顺序的
 			 compareTo() 返回 负数 
 		TreeSet在存储对象的时候  要求对象必须要有一个自然顺序
 			如何有自然顺:
 				1.让类 实现Comparable接口
 				  重写compareTo()方法
 		当添加元素的时候
 			ts.add(对象1)   对象1是  compareTo()方法中的 this
 						  对象1是  compareTo()方法中的 o
 			ts.add(对象2) 
 						对象2是  compareTo()方法中的 this
 						 对象1是  compareTo()方法中的 o
 			ts.add(对象3) 
 						对象3是  compareTo()方法中的 this
 						对象1是  compareTo()方法中的 o	
 						对象2是  compareTo()方法中的 o
 
 				2.另写一个类 作为 比较器
 					implements  Comparator接口
 					重写compare()
 */
public class TestTreeSet {

	public static void main(String[] args) {
	
		Cat c1 = new Cat();
		Cat c2 = new Cat();
		Cat c3 = new Cat();
		c1.name = "小尾巴";
		c1.age = 3 ;
		c2.name = "大尾巴";
		c2.age = 2 ;
		c3.name = "qwe";
		c3.age = 2;
		TreeSet<Cat> ts = new TreeSet<Cat>();
		ts.add(c1);
		ts.add(c2);
		ts.add(c3);
//		System.out.println(ts);
			
		/*
		TreeSet ts = new TreeSet();
		ts.add("甠");
		ts.add("生");
		ts.add("在");
		ts.add("五");
		System.out.println(ts);
		System.out.println('在'+0);*/
		/*
		 * 此处的a和b的比较顺序 是根据ASCII码比较的
		 * 字符串中的hashCode()是根据ASCII计算
		 * ASCII码小  哈希值也小
		 * 
		 * 汉字 也是 字符  也有对应的 ASCII码
		 */
//		System.out.println("生".compareTo("甠"));
		
			/*
			for(char ch = 10000 ;ch<30000;ch++) {
				System.out.println(ch+"="+(ch+0));
			}*/	
	}

}

class Cat implements Comparable{     //实现Compareable接口,并重写里面的compareTo()方法
	String name;
	int age;
	/**
	 *  "x".compareTo("y");
	 *  返回 负数   证明  x 小于 y 
	 *  返回 整数   证明  x 大于 y 
	 *  返回 0   证明  x 等于 y 
	 */
	@Override
	public int compareTo(Object o) {   
		System.out.println("this==="+this);
		System.out.println("o==="+o);
		System.out.println("********************");
		if(this == o) {
			return 0;
		}
		if(o instanceof Cat) {
			Cat c = (Cat)o;
			if(this.age == c.age) {
				return this.name.compareTo(c.name);
			}
			return this.age - c.age;
		}
		return 0;
	}
	@Override
	public String toString() {
		return "name=" + name + ", age=" + age;
	}
	
}

2.比较器排序

比较器排需要在TreeSet初始化是时候传入一个实现Comparator接口的比较器对象,或者采用匿名内部类的方式new一个Comparator对象,重写里面的compare()方法

package day0302.a;

import java.util.TreeSet;

public class TestTreeSet02 {

	public static void main(String[] args) {
		StudentBJQ bjq = new StudentBJQ();
		Student s1 = new Student();
		s1.name = "张三";
		s1.age = 21;
		s1.sg = 17.5;
		Student s2 = new Student();
		s2.name = "张三1";
		s2.age = 21;
		s2.sg = 17.5;
		TreeSet<Student> ts = new TreeSet<Student>(bjq);
		ts.add(s1);
		ts.add(s2);
		System.out.println(ts);
	}

}

比较器

package day0302.a;

import java.util.Comparator;

/**
 * 用来比较Student对象的 一个比较器
 * @author AirBird
 *
 */
public class StudentBJQ implements Comparator<Student>{
	/*
	 * o1 === this
	 * o2 ===  o
	 */
	@Override
	public int compare(Student o1, Student o2) {
		//1.根据年龄比较
		if(o1.age == o2.age) {
			//2.根据身高比较
			if(o1.sg == o2.sg) {
				return o1.name.compareTo(o2.name);
			}
			return  (int) (o1.sg - o2.sg);
		}
		return o1.age - o2.age;
	}

}

21.7 LinkedHashSet

LinkedHashSet 底层数据结构采用链表和哈希表共同实现,链表保证了元素的顺序与存储顺序一致,哈希表保证了元素的唯一性。线程不安全,效率高。

package day0302.a;

import java.util.HashSet;
import java.util.Iterator;

/*
  Collection
  		List	有序有索引 元素可重复
  			ArrayList  10    1    * 1.5
  			Vector	   10    1    * 2
  			LinkedList
  			Stack
  		Set		无序无索引 元素不可重复
  			HashSet    如果元素重复 存不进去
  					   初始容量 16   0.75   * 2
  					   底层实现是 HashMap的键
  					  根据hash值存储的顺序
  			TreeSet
 */
public class TestHashSet {
	public static void main(String[] args) {
		Dog d1 = new Dog();
		Dog d2 = new Dog();
		Dog d3 = new Dog();
		d1.name="大黄";
		d1.age=3;
		d2.name = "qwe";
		d2.age =3;
		
		HashSet<Dog> hs = new HashSet<Dog>();
		hs.add(d1);
		hs.add(d2);
		System.out.println(hs);
		System.out.println(d1.equals(d2));//true
		System.out.println(d1.hashCode());
		System.out.println(d2.hashCode());
		//遍历
		Iterator<Dog> it = hs.iterator();
		while(it.hasNext()) {
			Dog d = it.next();
			System.out.println(d);
		}
		System.out.println("=================");
		for(Dog d:hs) {
			System.out.println(d);
		}
		/*
		HashSet<Integer> hs = new HashSet<Integer>();
		hs.add(8);
		hs.add(2);
		hs.add(5);
		hs.add(8);
		System.out.println(hs);
		*/
	}
}
class Dog{
	String name;
	int age;
	@Override
	public int hashCode() {
		return this.name.hashCode()+age;
	}
	
	@Override
	public boolean equals(Object obj) {
		
		if(obj == this) {
			return true;
		}
		if(obj instanceof Dog) {
			Dog d = (Dog)obj;
			if(d.age == this.age  && d.name.equals(this.name)) {
				return true;
			}
		}
		return false;
	}
	
	@Override
	public String toString() {
		return "name=" + name + ", age=" + age ;
	}
	
}

21.8 Map

  1. Map用于保存具有映射关系的数据,Map里保存着两组数据:key和value,它们都可以使任何引用类型的数据,但key不能重复。所以通过指定的key就可以取出对应的value。

  2. Map 没有继承 Collection 接口, Map 提供 key 到 value 的映射

    map的主要方法

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XiGZ7E6c-1648275882439)(images/20180803205119738.png?lastModify=1646276086?lastModify=1646276086?lastModify=1646276086?lastModify=1646276086)]

21.9 HashMap

package day0302.a;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Set;

/*
   Map
   	HashMap  存储的数据是 一个映射关系
   		键 key		不允许重复  允许为空
   		值 value		允许重复     允许为空
   		扩容机制跟hashSet一致
   	存储规则:
   		根据键的哈希值 进行的 存储
   	键集:Set
   	值集:Collection   (List)
 */
public class TestHashMap {

	public static void main(String[] args) {
		HashMap<Integer,String> hm = new HashMap<Integer,String>();
		hm.put(3, "qwe");
		hm.put(1, "asd");
		hm.put(2, "zxc");
		System.out.println(hm);
		Set<Entry<Integer, String>>  s = hm.entrySet();
		for(Entry<Integer, String> e : s) {
			System.out.println(e.getKey()+"---"+e.getValue());
		}		
		/*
		HashMap hm = new HashMap();	//此时是一个空集合
		//添加元素
		hm.put(3, null);//当添加第一个元素的时候  容量为16
		hm.put(1, "zhangsan");
		hm.put(2, null);
		hm.put(1, "wangwu");
		hm.put(null, "wangwu");
		
		//修改元素  可以根据键 修改 值
		hm.put(null, "zhaoliu");
		//删除元素  根据键 删除  键和值
		Object o =hm.remove(null);
		System.out.println(o);//zhaoliu
		//查 根据键查值
		Object o1 =  hm.get(1);
		System.out.println(o1);
		System.out.println(hm);
		//遍历
		//1.获取键集
		Set s = hm.keySet();
		for (Object object : s) {
			System.out.println(object+"="+hm.get(object));
		}
		System.out.println("=======获取 值集合===========");
		//获取 值集合
		Collection coll = hm.values();
		Iterator it = coll.iterator();
		while(it.hasNext()) {
			Object obj = it.next();
			System.out.println(obj);
		}
		System.out.println("=======获取映射关系===========");
		Set ss = hm.entrySet();
		for (Object object : ss) {
			System.out.println(object);
		}
		*/
	}

}

21.10 TreeMap

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z3whVyiJ-1648275882440)(images\20180803205736499.png)]

package day0302.a;

import java.util.TreeMap;
/**
 * TreeMap存储 对象映射的时候
 * 		键 必须有一个  自然顺序  跟TreeSet类似
 * 		   TreeMap的键 不允许为 null
 *			存储的顺序是根据 键的自然顺序 来的
 */
public class TestTreeMap {

	public static void main(String[] args) {
		Pig p = new Pig();
		TreeMap<Pig,String> tm = new TreeMap<Pig,String>();
		tm.put(null, "qwe");
	}
}
class Pig{
	
}

HashMap和HashTable的比较[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BiCgxBgY-1648275882441)(images\20180803205546704.png)]

总结:各种集合适用场景

HashMap和HashTable:HashMap去掉了HashTable的contains方法,但是加上了containsValue()和containsKey()方法。HashTable同步的,而HashMap是非同步的,效率上比HashTable要高。HashMap允许空键值,而HashTable不允许。

HashMap:适用于Map中插入、删除和定位元素。
Treemap:适用于按自然顺序或自定义顺序遍历键(key)。

线程安全集合类与非线程安全集合类
LinkedList、ArrayList、HashSet是非线程安全的,Vector是线程安全的;
HashMap是非线程安全的,HashTable是线程安全的;
StringBuilder是非线程安全的,StringBuffer是线程安全的。

数据结构
ArrayXxx:底层数据结构是数组,查询快,增删慢
LinkedXxx:底层数据结构是链表,查询慢,增删快
HashXxx:底层数据结构是哈希表。依赖两个方法:hashCode()和equals()
TreeXxx:底层数据结构是二叉树。两种方式排序:自然排序和比较器排序
————————————————

22.1 File

  1. java.io.File类代表硬盘上的一个文件或者目录

  2. Java中文件或者目录的路径表示

    Windows中文件或者目录的表示D:\lujianliang\1.txt

    Java中文件或者目录的表示D:\lujianliang\1.txt,或者D:/lujianliang/1.txt

  3. java.io.File类作用每个File类的对象表示一个磁盘文件或目录,其对象属性中包含了文件或目录的相关信息,如名称、长度、所含文件个数等,调用它的方法则可以完成对文件或目录的常用管理操作,例如,创建、删除等操作。

绝对路径和相对路径

相对路径 不带盘符

绝对路径 带盘符
​ a f:\aaa\a.txt
​ b …/ab/b.txt

File常用类

File类常用方法

boolean createNewFile() 创建一个新文件

boolean mkdir() / mkdirs() 创建新的目录

boolean delete() 删除文件或者目录

void deleteOnExit() 虚拟机退出时删除文件或者目录

boolean exists() 判断当前文件或者目录是否存在

boolean isFile() 判断File对象代表的是否是一个文件

boolean isDirectory() 判断File对象代表的是否是一个目录

String getPath() 返回当前File对象的字符串路径

String getName() 返回当前File对象的文件名或者目录名

String getParent() 返回当前File对象的父级目录

String getAbsolutePath() 返回当前File对象的绝对路径

String[]list() 返回当前File对象包含的子目录以及文件

package day0307.b;

import java.io.File;
import java.io.IOException;

public class FileTest {

	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		File f1 = new File("E:\\取名废物\\aaa.txt");
		File f2 = new File("E:\\aaa.txt");
	//创建一个新的文件夹   
	//mkdir()    创建一个新的文件夹 
	//mkdirs()   创建多个文件夹		
		boolean b1=f1.mkdirs();  //用布尔值接收,判断是否新建成功
		System.out.println(b1);
		boolean b2=f2.mkdirs();  //用布尔值接收,判断是否新建成功
		System.out.println(b2);
	// createNewFile()  创建一个新的文件  
		
	//mkdir()和createNewFile()区别:
	//mkdir()只能创建文件夹   例:以 aaa.txt为名的文件夹
	//createNewFile()  可以创建文件后缀名类型的文件
		File f3 = new File("E:\\取名废物\\a3.txt"); 
		boolean b3=f3.createNewFile();
		System.out.println(b3);
		
	//delete() 删除文件 (不能删除非空文件)	
		boolean b4 = f1.delete();
		System.out.println(b4);
		
	//exists() 文件或目录是否存在	
		System.out.println(f1.exists());
	//
		System.out.println(f1.getPath());
		System.out.println(f1.getName());
		
      
//		System.out.println(f.getAbsolutePath());
//		String[]  strF = f.list();
//		for (String str : strF) {
//			System.out.println(str);
//		}
//		File[] ff = f.listFiles();
//		for (File file : ff) {
//			System.out.println(file);
//		}
		System.out.println("======================");
		System.out.println(f.getFreeSpace()>>30);
		System.out.println(f.getTotalSpace()>>30);
		
		System.out.println(f.lastModified());
		Date d = new Date(1000*60*60*24*365);
		//格林威治时间
		System.out.println(d);
		/*
		 * 此类可以将  日期 Date 格式化成String
		 * 还可以将String 解析成  日期  Date
		 */
		SimpleDateFormat sdf = new SimpleDateFormat("----MM月dd日yyyy  HH:mm:ss SSS");
		//格式化
		String dateStr = sdf.format(d);
		System.out.println(dateStr);
		//解析 String 解析成  日期  Date
		String  s = "200年3月4日";
		SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy年MM月dd日");
		Date  d1 = sdf1.parse(s);
		
		System.out.println(d1);
		System.out.println(	d1.getTime());

	}

}

递归

1.普通递归练习

package day0303.b;
/**
 * 参数传递:
 * 		值传递      传递基本类型的值的时候 
 * 				相当于 将基本值 “复制” 了一份 传递到方法中
 * 		引用传递
 * 				传递的是地址  虽然是两个不同作用域的 变量 
 * 				但引用的是  同一个对象
 *
 */
public class TestDiGui {
	// int i 形参
	static void mm(int i) {
		System.out.println(i);//1
		i++;//2
		if(i <= 10) {
			mm(i);
		}
		System.out.println(i);//2
	}
	
	public static void main(String[] args) {
		System.out.println("程序开始");
		int i = 1;
		//实参
		mm(i);
		System.out.println(i);//1
		System.out.println("程序结束");
	}

}

2.运用递归方式删除某文件下所有文件

package day0303.b;

import java.io.File;

public class WanNengShanChuRuanJian {
	//删除文件及文件夹的方法
	public static void mm(File f) {
		File[] files = f.listFiles();
		for (int i = 0; i < files.length; i++) {
			if(files[i].isDirectory()) {
				mm(files[i]);
			}
			files[i].delete();
		}	
	}

}

23. IO流

1.什么是流

流是一组有序的,有起点和终点的字节集合,是对计算机中数据传输的总称或者抽象即数据在两个设备间的传输称为流,流的本质是数据传输。

流序列中的数据可以是没有进行加工的原始数据(二进制字节数据),也可以是经过编码的符合某种格式规定的数据,Java中提供了不同的流类对它们进行处理。

2.流的分类

​ (1)按照流传输方向不同

​ 输入流(InputStream) 输出流(OutputStream)

​ (2)按照处理数据类型的不同

​ 字节流 字符流

​ 输入流(InputStream) 字节输入流

​ Reader 字符输入流
​ 输出流(OutputStream) 字节输出流
​ Writer 字符输出流

​ (3)按照流的基本功能不同

​ 节点流 过滤流

package day0307.b;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class IOtest01 {

	public static void main(String[] args) {
		
		FileInputStream fis = null;
		try {
			fis = new FileInputStream("D:\\Java项目\\src\\day0307\\b\\io.txt");
	//read()  读取字节		
	/*		一次只读取 一个字节,
	 *      读取的是当前字节的字符编码int类型,需要int强转char  (char)fis.read()
	 *      当读取不到数据的时候  返回 -1
	 */
			int a = -1;
			while ((a = fis.read())!= -1) {
				System.out.print((char)a);
			}
			
		//	System.out.println((char)fis.read());  //int强转char
		} catch (FileNotFoundException e) {
			
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			try {
				if (fis != null) {
					fis.close();
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}

}

package day0307.b;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;

public class IOtest02 {
	public static void main(String[] args) throws Exception {
		//字节输出流
		FileOutputStream fos = new FileOutputStream("D:\\Java项目\\src\\day0307\\b\\io.txt",true);
		//2.输出的内容
		String s1 = "Let the good times roll";
		String s2 = "Friend.";
		
		//3.输出
		//fos.write(s1.getBytes()); 
		//getBytes(),  String类中的方法,将string类型的字符串转化为字节类型
		fos.write(s2.getBytes());
		
		//4.刷新
		fos.flush();
		
		//5.关闭资源
		fos.close();
		
	}

}

package day0308.a;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.SequenceInputStream;
import java.util.Vector;

public class TestHeBing {
	public static  void mm1() {
		FileInputStream f1 = null;
		FileInputStream f2 = null;
		SequenceInputStream  sis = null;
		
		try {
			f1 = new FileInputStream("asd.txt");
			f2 = new FileInputStream("F:\\城市未来\\代码\\javase\\src\\com\\cswl\\d12z\\io\\aaa.txt");
			
			
			sis = new SequenceInputStream(f1,f2);
			byte[] b = new byte[1024];
			while(sis.read(b) != -1) {
				System.out.print(new String(b));
			}
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public static void main(String[] args) {
		FileInputStream f1 = null;
		FileInputStream f2 = null;
		//合并流
		SequenceInputStream  sis = null;
		//字节流转换成 字符流
		InputStreamReader  isr = null;

		try {
			f1 = new FileInputStream("asd.txt");
			f2 = new FileInputStream("F:\\城市未来\\代码\\javase\\src\\com\\cswl\\d12z\\io\\aaa.txt");
			Vector<InputStream> v = new Vector<InputStream>();
			v.add(f2);
			v.add(f1);
			sis = new SequenceInputStream(v.elements());
			isr = new InputStreamReader(sis);
			int i = -1;
			while((i=isr.read()) != -1) {
				System.out.print((char)i);
			}
			
			
			/*
			int i = -1;
			while((i = sis.read()) != -1) {
				System.out.print((char)i);
			}*/
			
			/*byte[] b = new byte[1024];
			while(sis.read(b) != -1) {
				System.out.print(new String(b));
			}*/
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

package day0308.a;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.InputStream;

/*
 * 字节流
 * 		适合传输 媒体文件  但不适合传输 文本
 * 
 * 	InputStream is = new FileInputStream("asd.txt");
	is.read();
	is.read();
	System.out.println(is.available());
			
 *如果读取文本 最好用字符流、
 		输入
 			Reader
 		输出
 			Writer
 * 
 */
public class TestReader {

	public static void main(String[] args) {
		FileReader fr = null;
		try {
			fr = new FileReader("asd.txt");
		/*	int i=fr.read();
			System.out.print((char)i);*/	
			/*int i = -1 ;
			while( ( i= fr.read()) != -1) {
				System.out.print((char)i);	
			}*/
				
			char[] ch = new char[1024];
			fr.read(ch);
			
			System.out.println( new String(ch) );
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (fr != null) {
					fr.close();
				} 
			} catch (Exception e2) {
				e2.printStackTrace();
			}
		}
	}

}

package day0308.a;

import java.io.FileWriter;
import java.io.IOException;

public class TestWriter {

	public static void main(String[] args) {
		try(FileWriter fw = new FileWriter("asd.txt",true);){
			String s = "胜多负少的123";
			fw.write(s);
			fw.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}

package day0308.a;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
/**
  java.io.NotSerializableException  未序列化异常
 序列化:.....
   Serializable  让类可以实现 序列化的功能
 * 
 *  
 */
public class TestGuoLvLiu {
	public static void sc() throws Exception {
		Dog d1 = new Dog("大黄",3);
		d1.id = "3456";
		Dog d2 = new Dog("大白",3);
		Dog d3 = new Dog("大黑",3);
		//String o1 = new String();
		ArrayList<Dog>  al = new ArrayList<Dog>();
		al.add(d1);
		al.add(d2);
		al.add(d3);
		
		FileOutputStream fos = new FileOutputStream("asd.txt");
		ObjectOutputStream oos = new ObjectOutputStream(fos);
		oos.writeObject(al);
		
		oos.flush();
		oos.close();
	}
	public static void sr() throws Exception {
		FileInputStream fis = new FileInputStream("asd.txt");
		ObjectInputStream  ois = new ObjectInputStream(fis);
		//反序列化
		ArrayList<Dog>  dog = (ArrayList<Dog>)ois.readObject();
		System.out.println(dog.get(2).getName());
		System.out.println(dog.get(2).getAge());
		System.out.print(dog.get(2).id);
	}
	
	public static void main(String[] args) throws Exception {
		//sc();
		sr();
		
		
		/*
		FileInputStream fis = new FileInputStream("asd.txt");
		DataInputStream dis = new DataInputStream(fis);
		double dd = dis.readDouble();
		System.out.println(dd);
		*/
		/*
		FileOutputStream fos = new FileOutputStream("asd.txt");
		//传输基本类型的数据
		DataOutputStream dop = new DataOutputStream(fos);
		String s = "12.5";
		Object o = new Object();
		double d = 12.5;
		Double dou = new Double(12.5);
		//fos.write(s.getBytes());
		dop.writeDouble(d);
		
		fos.flush();
		fos.close();
		*/
	}

}

{
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}

}




```java
package day0307.b;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;

public class IOtest02 {
	public static void main(String[] args) throws Exception {
		//字节输出流
		FileOutputStream fos = new FileOutputStream("D:\\Java项目\\src\\day0307\\b\\io.txt",true);
		//2.输出的内容
		String s1 = "Let the good times roll";
		String s2 = "Friend.";
		
		//3.输出
		//fos.write(s1.getBytes()); 
		//getBytes(),  String类中的方法,将string类型的字符串转化为字节类型
		fos.write(s2.getBytes());
		
		//4.刷新
		fos.flush();
		
		//5.关闭资源
		fos.close();
		
	}

}

package day0308.a;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.SequenceInputStream;
import java.util.Vector;

public class TestHeBing {
	public static  void mm1() {
		FileInputStream f1 = null;
		FileInputStream f2 = null;
		SequenceInputStream  sis = null;
		
		try {
			f1 = new FileInputStream("asd.txt");
			f2 = new FileInputStream("F:\\城市未来\\代码\\javase\\src\\com\\cswl\\d12z\\io\\aaa.txt");
			
			
			sis = new SequenceInputStream(f1,f2);
			byte[] b = new byte[1024];
			while(sis.read(b) != -1) {
				System.out.print(new String(b));
			}
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public static void main(String[] args) {
		FileInputStream f1 = null;
		FileInputStream f2 = null;
		//合并流
		SequenceInputStream  sis = null;
		//字节流转换成 字符流
		InputStreamReader  isr = null;

		try {
			f1 = new FileInputStream("asd.txt");
			f2 = new FileInputStream("F:\\城市未来\\代码\\javase\\src\\com\\cswl\\d12z\\io\\aaa.txt");
			Vector<InputStream> v = new Vector<InputStream>();
			v.add(f2);
			v.add(f1);
			sis = new SequenceInputStream(v.elements());
			isr = new InputStreamReader(sis);
			int i = -1;
			while((i=isr.read()) != -1) {
				System.out.print((char)i);
			}
			
			
			/*
			int i = -1;
			while((i = sis.read()) != -1) {
				System.out.print((char)i);
			}*/
			
			/*byte[] b = new byte[1024];
			while(sis.read(b) != -1) {
				System.out.print(new String(b));
			}*/
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

package day0308.a;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.InputStream;

/*
 * 字节流
 * 		适合传输 媒体文件  但不适合传输 文本
 * 
 * 	InputStream is = new FileInputStream("asd.txt");
	is.read();
	is.read();
	System.out.println(is.available());
			
 *如果读取文本 最好用字符流、
 		输入
 			Reader
 		输出
 			Writer
 * 
 */
public class TestReader {

	public static void main(String[] args) {
		FileReader fr = null;
		try {
			fr = new FileReader("asd.txt");
		/*	int i=fr.read();
			System.out.print((char)i);*/	
			/*int i = -1 ;
			while( ( i= fr.read()) != -1) {
				System.out.print((char)i);	
			}*/
				
			char[] ch = new char[1024];
			fr.read(ch);
			
			System.out.println( new String(ch) );
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (fr != null) {
					fr.close();
				} 
			} catch (Exception e2) {
				e2.printStackTrace();
			}
		}
	}

}

package day0308.a;

import java.io.FileWriter;
import java.io.IOException;

public class TestWriter {

	public static void main(String[] args) {
		try(FileWriter fw = new FileWriter("asd.txt",true);){
			String s = "胜多负少的123";
			fw.write(s);
			fw.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}

package day0308.a;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
/**
  java.io.NotSerializableException  未序列化异常
 序列化:.....
   Serializable  让类可以实现 序列化的功能
 * 
 *  
 */
public class TestGuoLvLiu {
	public static void sc() throws Exception {
		Dog d1 = new Dog("大黄",3);
		d1.id = "3456";
		Dog d2 = new Dog("大白",3);
		Dog d3 = new Dog("大黑",3);
		//String o1 = new String();
		ArrayList<Dog>  al = new ArrayList<Dog>();
		al.add(d1);
		al.add(d2);
		al.add(d3);
		
		FileOutputStream fos = new FileOutputStream("asd.txt");
		ObjectOutputStream oos = new ObjectOutputStream(fos);
		oos.writeObject(al);
		
		oos.flush();
		oos.close();
	}
	public static void sr() throws Exception {
		FileInputStream fis = new FileInputStream("asd.txt");
		ObjectInputStream  ois = new ObjectInputStream(fis);
		//反序列化
		ArrayList<Dog>  dog = (ArrayList<Dog>)ois.readObject();
		System.out.println(dog.get(2).getName());
		System.out.println(dog.get(2).getAge());
		System.out.print(dog.get(2).id);
	}
	
	public static void main(String[] args) throws Exception {
		//sc();
		sr();
		
		
		/*
		FileInputStream fis = new FileInputStream("asd.txt");
		DataInputStream dis = new DataInputStream(fis);
		double dd = dis.readDouble();
		System.out.println(dd);
		*/
		/*
		FileOutputStream fos = new FileOutputStream("asd.txt");
		//传输基本类型的数据
		DataOutputStream dop = new DataOutputStream(fos);
		String s = "12.5";
		Object o = new Object();
		double d = 12.5;
		Double dou = new Double(12.5);
		//fos.write(s.getBytes());
		dop.writeDouble(d);
		
		fos.flush();
		fos.close();
		*/
	}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值