JavaSE

写代码:

    1,明确需求。我要做什么?

    2,分析思路。我要怎么做?1,2,3。

    3,确定步骤。每一个思路部分用到哪些语句,方法,和对象。

    4,代码实现。用具体的java语言代码把思路体现出来。

 

学习新技术的四点:

    1,该技术是什么?

    2,该技术有什么特点(使用注意):

    3,该技术怎么使用。demo

    4,该技术什么时候用?test。

JavaSE笔记

Java简介

Java发布于1995年5月23日,Java前身是Oak,衍生自C++,Java之父是詹姆斯·亚瑟·高斯林,Java最早是sun公司的产品,2009年被Oracle公司收购,现属于Oracle公司的产品。

Java的版本

最初版本

1995年1.0版本;1.1版本

Java2平台

1.2 1.3 1.4 5.0

走出Java2

6

易主Oracle

2011年7,8

新的举措,每半年发布一个版本

9,10,11,12,13...

Java的版本类型

1.JavaSE,Java标准版本,可以开发Java控制台程序,桌面程序等,为JavaEE提供基础

2.JavaEE,Java企业级版本,现在以捐献给eclipse基金会,改名为雅加达EE(JakartaEE)。它是一套规范,由第三方对它具体实现,如tomcat、WebLogic等。在实际开发中,一般使用框架来代替它

3.JavaME,Java微版本,开发电冰箱,机顶盒,电烤箱,功能手机等设备中的嵌入式程序。

但智能手机程序不用Java ME开发。

Java语言特点

简单易学 废弃c中的指针操作

跨平台 不区分系统=》编译一次。到处执行

面向对象

健壮性

动态性

分布式

多线程

Java平台的组成部分

JVM:Java虚拟机额,使Java程序跨平台

JRE:Java运行环境,包含JVM,以及常用类库,运行Java程序的最小单位

JDK:Java开发工具包,包含JRE,以及编译工具,打包工具等,开发Java程序的最小单位

基本windows的DOS命令:

打开DOS命令窗口:

开始菜单-->运行-->输入cmd-->回车【快捷键:Windows+R】

常见的命令:

exit:退出当前命令窗口

cls:清屏

dir:列出当前目录下所有的子文件/子目录

del *class:删除class文件

cd ..:回到上一级

cd \:直接回到根目录

c: d: e: 回车 切换盘符

第一个Java程序

创建项目:File→New(Other)→Java Project →Project name →Finish →no

创建包:src右键→new→Package→Name→Finish

创建类:在包上右键→New→Class→Name→Finish

注释

// :单行注释

/**/:多行注释

/** */:文档注释

注意:这种注释是比较专业的注释,它会被javadoc.exe工具解析提取并生成帮助文档。

输出语句

  1. 不换行输出:System.out.print("");

  2. 换行输出:System.out.println("");

转义字符\

双引号:"

单引号:'

反斜线:\

制表符:\t(Tab键,适合不对齐的输出)

换行:\n

第一个Java程序

public 公共的 class类 static 静态的 void 没有返回值(空)

main 方法名 String 字符串

(String[] args(可以自己起))是一个main方法的参数列表

System系统 out输出 println打印并换行

//定义包
package cn.etc.java.d0810;
//定义类,类名要和文件名必须一致,类体中不可以直接编写Java语句,声明变量除外
public class Hello {
    //主方法,是一个程序的入口
    public static void main(String[]args) {
        /*
         *  输出语句:
         *  1.不换行输出:System.out.print();
         *  2.换行输出:System.out.println();
         * 
         *  转义字符:\
         *  1.双引号:\"
         *  2.单引号:\'
         *  3.反斜线:\\
         *  4.制表符:\t(Tab键,适合不齐的输出)
         *  5.换行:\n
         */
        System.out.println("高斯林");
        System.out.println("1955");
        System.out.println(2021-1955);
        //Hello "World"
        System.out.println("Hello\nWorld");
//      System.out.println("Hello");
//      System.out.println("World");
    }
}
​

public class 和class的区别:

一个java源文件当中可以定义多个class

一个java源文件当中public的class不是必须的

一个class会定义生成一个xxx.class字节码文件 一个java源文件当中定义公开的类的话,只能有一个,并且该类名称必须和java源文件名称一致。

每一个class当中都可以编写main方法,都可以设定程序的入口,想执行B.class中的main方法: java B, 想执行x.class当中的main方法:java x

注意: 当在命令窗口中执行java Hello,那么要求Bello.class当中必须有主方法。没有主方法会出现运阶段的错误: D:l courseavaProjects\02-JavasE\day02>java Hello

错误:在类B中找不到主方法,请将主方法定义为:

public static void main (string[]args)

JAVA和JAVAC命令的作用

JAVAC:作用是JAVA编译器将.java文件编译生成.class字节码文件

JAVA:java命令作用是指JAVA解释器用于将.class字节码文件解释并执行

数据类型

作用:指在jvm运行程序的时候给该数据分配多大的内存空间

1.基本数据类型

整数类型

byte 字节型 1个字节 8位 范围:-128~127

short 短整型 2个字节 16位 范围:-32768~32767

int(默认) 整型 4个字节 32位 范围:约正负21亿

long 长整型 8个字节 64位 范围:约正负92亿 后缀:L或l

浮点类型

float 单精度 4个字节 32位 后缀:F或f

double 双精度 8个字节 64位 后缀:D或d

字符类型 如:'a'(使用单引号)

char 字符型 2个字节 16位 范围:0~65535(\u0000~\uffff)

布尔类型

boolean 布尔型 1或4个字节 8或32位 值:true false

字节(byte):

1 Byte = 8 bit 1KB = 1024 Byte

1 MB = 1024 KB 1KB = 1024 MB

1 TB = 1024 GB

1 TB = 1024 * 1024 * 1024 *1024 * 8

最大值:2的7次方 - 1 = 127

最小值:-128

取值范围:【-128 ~ 127】

byte可以表示256个不同的二进制数字

2.引用数据类型

类类型(class)

字符串(String):多个字符组成了字符串,用引号表示,如“高斯林”,属于类类型(对象)

数组类型(array)

接口类型(interface)

枚举类型(enum)

注解类型(annotation)

变量

java中在使用数据之前,必须要先声明

变量:程序中可以改变的量

变量的三大要素(三大组成部分)

数据类型 变量名 变量值

1.声明变量:数据类型 变量名; 如:short age;

2.变量赋值:变量名 = 值;如:age = 18;

3.声明变量并赋值:数据类型 变量名 = 值; double score = 98.5;

4.声明多个同一类型的变量:数据类型 变量名1,变量名2...

5.访问一个变量有两种方式:

(1)读取变量中保存的具体数据 get/获取

(2)修改变量中保存的具体数据 set/设置

变量名的建议规范

变量名遵循驼峰命名法,即首字母小写,其后每个单词首字母大写

不建议使用汉字,尽量使用英文单词或拼音,要见名知意

不建议使用单个字母命名,约定俗成除外

不建议以下划线开头,不建议使用$

命名法:

驼峰命名法:classId

帕斯卡命名法:ClassId

蛇底式命名法:class_id

尖叫蛇底式命名法:CLASS_ID

标识符强制规范

1.可由字母,数字,下划线,$组成

2.不能以数字开头

3.字母区分大小写

4.不能使用关键字,字面量,保留字命名

5.在同一作用域下同一种类型的名称不能重名

关键字:是Java定义好的具有特定含义的单词,如:public,int,class...

保留字:是Java的前身Oak和前代语言C、C++中的关键字,但是在Java中没有使用却保留下来的。goto,const

字面量:是Java定义好的一些值。如:true,false,null

命名习惯:

类名,接口名等:首字母大写,多个单词每个单词首字母均大写 Animal HelloWorld

方法名:小写,多个单词, 第二个单词之后首字母大写 main getName

变量名:小写,多个单词, 第二个单词之后首字母大写 name age stuName

包名:小写

常量名字:大写

    public static void main(String[] args) {
//      double score;
//      score = 95.5;
        double score = 95.5;
        //字符串拼接:+
        System.out.println("成绩:"+score);
        System.out.println("score");
        //错误写法,num没赋值
//      int num;
//      System.out.println(num);
        
        int a = 10,b,c;
        System.out.println(a);
    }
    public static void main(String[] args) {
        //整数型声明并赋值
        byte b = 127;
        short s = 32767;
        int i = 222222222;
        // 默认是int类型,long超出int范围需要加L/l
        long l = 111111111111111L;
        
        //浮点型声明赋值,默认是double 单精度必须加F/f
        float f = 3.14F;
        double d = 4.5;
        
        //字符型
        char c1 = 'a',c2 = '1',c3 = '你';
        
        //布尔类型 只能是true,false
        boolean b1 = false;
    }

控制台输入

Scanner 是用来输入的,首先定义一个Scanner

Scanner sc = new Scanner(System.in);

导入Scanner:

1.在package下面,写上import java.util.Scanner;

2.将鼠标放在Scanner上面,根据提示,选择...

3.将光标放在Scanner后面,按Alt+/(?)

4.使用快捷键:按Ctrl+Shift+o,会自动导入所有所需要的类

一般语法:sc.next类型(),类型要求首字母大写

输入double类型:sc.nextDouble();

输入int类型:sc.nextInt();

输入字符串String:sc.next();

没有char类型的输入

    public static void main(String[]args) {
        Scanner sc = new Scanner(System.in);
        System.out.print("请输入你的成绩:");
        double score = sc.nextDouble();
        System.out.print("请输入你的年龄:");
        int age = sc.nextInt();
        System.out.println("请输入你的姓名:");
        String name = sc.next();
        System.out.println("成绩:"+score+",年龄:"+age+",姓名:"+name);
    }
​

类型转换

1.自动类型转换(隐式类型转换)

范围小的类型转到范围大的类型

2.强制类型转换(显示类型转换)

范围大的类型转到范围小的类型

(想要转到的类型)变量

强制类型转换可能会出现溢出(精度丢失)

3.在八大基本类型中,除了boolean之外的七种类型都可以互相转换

public class ConvertDemo {
​
    public static void main(String[] args) {
        
//      int boxOffice = 22;
//      long num = boxOffice;
//      System.out.println(num);
        
        long boxOffice = 2222222222L;
        int num = (int)boxOffice;
        System.out.println(num);
        
//      byte b = 1;
//      short s = b;
        
//      short s = 1;
//      byte b = (byte)s;
        
        byte a = 98;
        char c = (char)a;
        System.out.println(c);
        
        float f = (float)2.2;
        
        byte num2 = (byte)128;
        //a:97 A:65
        int i = 68;
        char cc = (char)i;
        System.out.println(cc);
    }
​
}

字符串转基本类型

一般语法:数据类型.parse数据类型(字符串),数据类型首字母大写

double score = Double.parseDouble("96.5");

1.字符串转int类型:Integer.parseInt(字符串);

int port = Integer.parseInt("3306");

2.对于字符串转布尔类型,如果字符串是true(不区分大小写),则结果是true,否则是false

3.没有转成char类型的方法

基本类型转字符串:

""+基本类型变量或者数值

2、小容量向大容量转换,称为自动类型转换,容量从小到大排序:

byte < short < int < long< f1oat < doubie<char 注意: 任何浮点类型不管占用多少个字节,都比整数型容量大。 char和short可表示的种类数量相同,但是char可以取更大的正整数

3、大容量转换成小容量,叫做强制类型转换,需要加强制类型转换符,程序才能编译通过,但是在运行阶段可能会损失精度,所以谨慎使用。

4、当整数字面值没有超出byte, short , char的取值范围,可以直接赋值给byte , short ,char类型的变量。

5、byte ,short, char混合运算的时候,各自先转换成int类型再做运算。6、多种数据类型混合运算,先转换成容量 最大的那种类型再做运算。

public class StringConvertDemo {
    
    public static void main(String[] args) {
        
        String strScore = "95.5";
        System.out.println(strScore+1);
        double score = Double.parseDouble(strScore);
        System.out.println(score+1);
        
        String strPort = "3306";
        int port = Integer.parseInt(strPort);
        
        boolean ok = Boolean.parseBoolean("aaaa");
        System.out.println(ok);
        
        int a = 10;
        String str = ""+a;
    }
​
}

运算符

算数运算符,赋值运算符,关系运算符,逻辑运算符,条件运算符

算数运算符

+,-,*,/,%,++,--

1.两个整数相除的结果为整(即整),若想得到小数结果,需要将其中一个强制类型转换为浮点型 利用整除可以去掉最后一位:数/10 2.浮点类型的计算不一定精准(加减乘除)

3.取余数:

1)负数取余数,以第一个数的正负为准,若第一个数是正数,则结果为正,若第一个数是负数,则结果为负

2)判断奇偶:数%2,若结果是0则是偶数,若结果为非0则是奇数

3)获取整数的最后一位:数%10

4)判断整数:数%1,若结果是0则是整数,若结果非0则是浮点数

4.两种类型进行计算的结果 1)都是整数类型,若有long类型参与,则结果为long类型,否则为int类型 2)若有浮点类型参与,如果有double类型参与,则结果为double类型,否则float类型

5.除了boolean之外的七种类型,都可以进行算数运算

6.++ 、-- ++:自加1 --:自减1 int i = 1; i++;//i变为2

i++和++i的区别 i++:先用后加,先人后己 ++i:先加后用,先己后人

//习题 int j = 1; //int sum3 = ++j + j++; int y1 = ++j;//j=2 y1=2 int y2 = j++;//j=3 y2=2 int sum3 = y1+y2;//4 System.out.println(j);//3 System.out.println(sum3);//4

int aa = 1; aa = aa++; ... System.out.println(aa);//值永远不变 在一行上,不建议写多个i++或者++i,违反了KISS原则。KISS:简单既是美

public class OperatorDemo01 {
​
    public static void main(String[] args) {
        System.out.println(1+2);
        System.out.println(5-1);
        System.out.println(2*6);
        System.out.println(5/(double)2);
        System.out.println(123/10);
        System.out.println(0.1+0.2);
        System.out.println(5%-2);
        System.out.println(-3%2);
        System.out.println(123%10);
        System.out.println(123.2%1);
        
        byte b = 10;
        byte c = 12;
        byte sum = (byte)(b+c);
        System.out.println(sum);
        
        int x1 = 10;
        float x2 = 2.5F;
        float sum2 = x1+x2;
        System.out.println(sum2);
        
        int i = 1;
        int a = ++i;
        System.out.println(i);
        System.out.println(a);
        
        //习题
        int j = 1;
        //int sum3 = ++j + j++;
        int y1 = ++j;//j=2 y1=2
        int y2 = j++;//j=3 y2=2
        int sum3 = y1+y2;//4
        System.out.println(j);
        System.out.println(sum3);
        
        int aa = 1;
        aa = aa++;
        aa = aa++;
        aa = aa++;
        System.out.println(aa);
    }
​
}

赋值运算符

1简单赋值运算符(普通赋值运算符):=

1)可以连续赋值

2)可以参与运算

2.复合赋值运算符:+=,-=,*=,/=,%=

short a = 1;

a += 2;//a变为3

a+=2与a=a+2并不完全一样,a+=2里边存在一个隐式的类型转换

相当于a=(a的类型)(a+2),结果是+=左边的类型

重要结论:扩展类的赋值运算符不改变运算结果类型,假设最初这个变量的类型是byte类型,无论怎么进行追加或追减,最终该变量的数据类型还是byte类型。

public class OperatorDemo02 {
    
    public static void main(String[] args) {
        int a = 10;
        int x1,x2,x3;
        x1 = x2 = x3 = 20;
        //两值交换
        int x = 1;
        int y = 13;
        
        //方式一
//      int z = x;
//      x = y;
//      y = z;
        //方式二
        x = x+y;//x=14
        y = x-y;//1
        x = x-y;//13
        System.out.println(x);
        System.out.println(y);
        
        int num1 = 3;
        int num2 = 5;
        num2 = (num1+num2) - (num1=num2);
        System.out.println(num1);
        System.out.println(num2);
        
        short score = 90;
        score += 5;
        //score = (short)(score+5);
        System.out.println(score);
        
    }
​
}
​

关系运算符

>,<,>=,<=,==(等于),!=(不等于)。结果为布尔类型:true/false

public class OperatorDemo03 {

	public static void main(String[] args) {
		int score = 9;
		System.out.print(score>=60);
	}

}

逻辑运算符

与,或,非,

与:并且,如果两个条件同时为true,则结果为true &&:短路与,如果第一个条件为false,则不会判断第二个条件 &:非短路与,即使第一个条件为false,也会判断第二个条件

或,或者,如果有一个条件为true,则结果为true ||:短路或:如果第一个条件为true,则不会判断第二个条件 |:非短路或:即使第一个条件为true,也会判断第二个条件

非:取反,true变false,false变true !

异或:两边的算子只要不一样,结果就是true

public class OperatorDemo04 {

	public static void main(String[] args) {
		int score = 800;
		System.out.println(score >= 0 && score <= 100);

		int a = 1;
		System.out.println(a < 0 & a++ > 0);
		System.out.println(a);
		// 年龄40岁以下可以入职,或者性别是女可以入职
		int age = 50;
		String gender = "女";
		System.out.println(age < 40 || gender == "女");
		
		boolean ok = true;
		System.out.println(!ok);
	}

}

条件运算符

布尔表达式 ? 表达式1 : 表达式2

布尔类型表达式 ? 结果为true执行此部分 : 结果为false时执行此部分

嵌套条件运算符:在问号或者冒号部分还有条件运算符

执行原理:

 

public class OperatorDemo05 {
​
    public static void main(String[] args) {
//      int score = 8;
//      String result = score>=60 ? "及格" : "不及格";
//      System.out.println(result);// >=90 A >=60B <60 C
        int score = 98;
        String result = score >= 90 ? "A" : score >= 60 ? "B" : "C";
        System.out.println(result);
​
        // 求a,b,c的最大值
        int a = 50;
        int b = 20;
        int c = 22;
​
        // 方式一
//      int max;
//      max = a > b ? a : b;
//      max = max > c ? max : c;
//      System.out.println(max);// 方式二
        int max;
        max = (a > b ? a : b) > c ? (a > b ? a : b) : c;
        System.out.println(max);
​
    }
}
​

【按操作数划分】

一元运算符(单目运算符):只有一个操作数,如:a++,-1

二元运算符(双目运算符):有两个操作数,如:a+b

三元运算符(三目运算符):有三个操作数,即?:

流程控制

选择结构:if, switch

1.分支语句:if

一、单分支

if(布尔表达式) {

//如果条件为true,则执行此部分代码 }

            int score = 90;
​
            if(score>=60){
​
                    system.out. print1n("及格");
            }
二、双分支

if(布尔表达式){

//如果条件为true,则执行此部分代码}else{

//否则执行此部分代码

}

当代码块语句是一句,执行语句时,登可以省略不写。

if

代码块;

else

代码块;

		int score = 90;
		if(score>=60) {
			system. out.print1n("及格");
        }else
			system.out.print7n("不及格");
三、多分支

if(条件1) {

//如果条件1为true,则执行此部分代码,不会判断下面的条件

}else

if(条件2){

//如果条件2为true,则执行此部分代码,不会判断下面的条件 }...

else{

//如果以上条件都不满足,则执行此部分代码

}

四、嵌套分支:

在if, else if, else部分还有分支语句

//>=90优秀		>=80良好		>=60中等		<60差
int score = 800;
if(! (score<O ll score>100)) {
	if(score>=90) {
		system. out.print7n("优秀");
    }else if(score>=80) {
		system. out. println("良好");
    }else if(score>=60) {
		system.out.print1n("中等");
    }else f
		system.out. print1n("差");
	}
	}else i
		system.out. print1n("不合法");
	}

重点:对于Java中的if语句来说,只要有一个分支执行,整个if语句全部结束。

注意:嵌套时要保证格式完美。

if语句分支中只有一条语句时,大括号可以省略(不推荐)

2.开关语句:switch

switch(变量) {

case值1:

//如果变量和值1相等,则执行此部分代码

break;

...

case值n:

//如果变量和值n相等,则执行此部分代码

break;

default:

//如果变量和以上值都不相等,则执行此部分代码

}

注意:

1.case贯穿: 如果没有break,会继续执行,直到遇见一个break或者程序结束

2.case后面必须是一个具体的值,不能是变量,也不能是多个值,也不能表示范围

3.case的值不能重复

4.swich支持的6种类型:byte,short,int,char,String(Java 7),枚举(Java 5)

思路:

1.选择所有数据从键盘输入

2.使用switch语句进行判断

3.需要从控制台输入三次:

(1) 第一个数字

(2)运算符

(3)第二个数字

循环结构:for,while,do..while

1.while循环 2.for循环 3.do-while循环 4.新型for循环

【while循环】

while(条件){

循环体

}

确定循环次数

1.初始变量

while(2.循环条件){

3.循环体

4.迭代因子

}

执行顺序:1234 234 234...

1、while循环的语法结构:

while(布尔老达式){

循环体; }

2、while循环的执行原理:

先判断布尔表达式的结果:

true

执行循环体

判断布尔表达式的结果:

false

循环结束

3、while循环的循环次数:

0~n次

注意:while循环的循环体可能执行次数为0。

public static void main(String[] args) {
//		int i = 1;
//		while(i<=2) {
//			System.out.println("跑了"+i+"圈");
//			i++;
//		}

		// 创建一个未知次数的循环
		Scanner sc = new Scanner(System.in);
		System.out.println("是否继续?Y/N");
		String answer = sc.next();
		while ("Y".equals(answer)) {
			System.out.println("欢迎使用");
			// 编写代码

			System.out.println("是否继续?Y/N");
			answer = sc.next();
		}
		System.out.println("程序结束");

	}

【for循环】

for(1.初始变量;2.循环条件;4.迭代因子){

3.循环体

}

执行顺序:1234 234 234...

【应用场景】

1.while循环适合不确定循环次数的场景

2.for循环适合确定循环次数的场景

语法结构:

for(初始化表达式;布尔表达式;更新表达式){

//是需要重复执行的代码片段【循环体:由java语句构成】 }

for循环的执行过程/执行原理?

初始化表达式、布尔表达式、更新表达式都不是必须的!【但是两个分号是必须的】

初始化表达式最先执行,并且在整个for循环当中只执行一次。

布尔表达式必须是true/false,不能是其它值。

for的执行过程:

先执行初始化表达式,并且该表达式只执行一次

判断布尔表达式的结果是true还是false

布尔表达式true

执行循环体

执行更新表达式

判断布尔表达式的结果是true还是false

布尔表达式false

循环结束

	for(int i=1;i<=2;i++) {
			System.out.println("跑了"+i+"圈");
		}

【do while】

1、do . .while循环的语法结构:

do{ 循环体; }while(布尔表达式);

2、do . .while循环的执行原理

3、do . .while循环的执行次数: do ..while循环的循环体代码片段执行次数是:1-N次【至少一次】

4、使用do ..while循环的注意事项: do . .while循环语句最终有一个"分号"别丢了。

1.初始变量

do{

3.循环体

4.迭代因子

}while(2.循环条件);

执行顺序:1342 342 342 ....

do while循环至少执行一次

		int i = 1;
		do {
			System.out.println("跑了"+i+"圈");
			i++;
		}while(i<=2);

嵌套循环

		/*
		 * 	嵌套循环 
		 * *** 
		 * *** 
		 * ***
		 */
		for(int j=1;j<=3;j++) {
			for(int i=1;i<=3;i++) {
				System.out.print("*");
			}
			System.out.println();
		}

1.迭代算法:是指不断由已知的条件推出新值的过程

		/*
		 * 	迭代算法:是指不断由已知的条件推出新值的过程
		 * 	斐波那契数列:1 1 2 3 5 8 13 21...个数由输入决定
		 * 				a  b c
		 * 				   a b c
		 * 					 a b c
		 * 	c = a+b;
		 * 	a = b;
		 * 	b = c;
		 */
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int a = 1;
		int b = 1;
		int c;
		for(int i = 1;i<=n;i++) {
			System.out.print(a+" ");
			c = a+b;
			a = b;
			b = c;
		}

穷举算法:是指遍历一个域穷尽其范围内的所有可能性

		/*
		 * 	穷举算法:是指遍历一个域穷尽其范围内的所有可能性
		 * 	例子:有一个未知数,这个数除以三余二,除以五余三,除以七余二,问你这个数是多少
		 */
		for(int i=1;;i++) {
			if(i%3==2 && i%5==3 && i%7==2) {
				System.out.println(i);
				break;
			}
		}

 

break:终止整个循环

1、break是java语言当中的关键字,被翻译为"中断/折断”

2、break + ";”可以成为一个单独的完整的java语句: break ;

3、break语句使用在switch语句当中,用来终止switch的语句执行。

4、 break语句同样可以使用在循环语句当中,用来终止循环的执行。

5、break终止哪个循环呢?

6、break;语句使用在for,while , do ..while循环语句当中用来跳出循环,终止循环的执行 因为当程序循环到某个条件的时候,后续的循环没必要执行了,再执行也是耗费资源,所以可以终止循环,这样可以提高程序的执行效率。

continue语句:

continue:终止本次循环,还会执行下次循环

1、continue表示:继续/go on/下一个

2、continue也是一个continue关键字加一个分号构成一个单独的完整的java语句,主要出现循环语句当中用来控制循环的执行。

3、break和continue的区别?

break表示循环不执行了,跳出循环,终止循环。 continue表示终止当前"本次"循环,直接进入下一次循环继续执行。

4、continue也有这样的语法: continue循环名称;【作为了解内容】

随机数

1.Math.random()生成0~1之间的随机小数

生成随机数[min,max) =>(int)(Math.random*(max-min)+min);

2.Random类

Random rand = new Random();

rand.nextInt(上限),生成0到上限-1之间的随机整数。[0,上限)

生成随机数[min,max) =>rand.nextInt(max-min)+min;

public static void main(String[] args) {
		/*
		 * 随机数 Math.random():生成0~1之间的随机小数
		 * 
		 * [0,10)随机整数:(int)(Math.random()*10)
		 * 
		 * 产生随机数[min,max) =》 (int)(Math.random()*(max-min)+min)
		 * 
		 */
		// [1,100) [0,99)+1
		System.out.println((int) (Math.random() * 99 + 1));

		// [50,80) [0,30)+50
		System.out.println((int) (Math.random() * 30 + 50));

		// 随机生成小写字母 a:97 z:122  A:65 Z:90
		// [0,26)
		System.out.println((char) (Math.random() * 26 +'a'));
		System.out.println((char) (Math.random() * 26 + 97));

		// 随机生成字母(不区分大小写)  
//		int num = (int) (Math.random() * 52);// [0,52)
//		if (num < 26) {// [0,26)
//			System.out.println((char) (num + 'a'));
//		} else {//[26,52)
//			System.out.println((char)(num-26 + 'A'));
//		}
		
		//随机生成字母(不区分大小写)或数字(0~9)
//		int num = (int)(Math.random()*62);
//		if(num<10) {
//			System.out.println(num);
//		}else if(num<36) {//[10,36)
//			System.out.println((char)(num-10+'a'));
//		}else {//[36,62)
//			System.out.println((char)(num-36+'A'));
//		}
		
		/*
		 * Random类
		 * Random rand = new Random();
		 * rand.nextInt(上限),[0,上限) 整数
		 */
		Random rand = new Random();
		System.out.println(rand.nextInt(10));
		//[1,10) [0,9)+1
		System.out.println(rand.nextInt(9)+1);
		
		
	}

字符串

	public static void main(String[] args) {
		//String简介
		String str = "hello!!";
		String str2 = "world";
		System.out.println(str.equals(str2));
		System.out.println(str.equals("hello"));
		//长度:字符串.length()
		System.out.println(str.length());
	}

数组

1.声明数组:数据类型[] 数组名;

数据类型 数组名[];不推荐

2.实例化数组:数组名 = new 数据类型[长度];

1+2=>3.声明并实例化数组:数据类型[] 数组名 = new 数据类型[长度];

注意:数组长度是int类型

4.使用数组:

1)为元素赋值:数组名[索引] = 值;

索引,下标,角标,下角标,从0开始,最大索引比长度小1

2)获取元素值:数组名[索引];

5.数组长度:数组名.length

	public static void main(String[] args) {
//		int[] scores;
//		scores = new int[3];
		int[] scores = new int[4];
		scores[0] = 90;
		scores[1] = 89;
		scores[2] = 88;
		scores[3] = 60;
		
        //遍历数组
        //方式一
//		for(int i=0;i<scores.length;i++) {
//			System.out.println(scores[i]);
//		}
		/*
		 * 	新型for循环,增强for循环,foreach循环,迭代循环,for冒号循环
		 * 	for(元素的数据类型 变量名 : 数组名){
		 * 		//每次循环,变量的值,就是数组中的每一个元素
		 * 	}
		 */
        //方式二
		for(int score : scores) {
			System.out.println(score);
		}
	}

6.数组默认值

整数类型:0

byte:(byte)0

short:(short)0

int:0

long:0L

浮点类型:

float:0.0F

double:0.0

字符类型:char \u0000,实际就是0

布尔类型:false

字符串:null

7.数组初始化

1)数据类型[] 数组名 = new 数据类型[]{元素1,元素2,...};

2)数据类型[] 数组名 = {元素1,元素2,...};此方式只能在声明数组时使用

	public static void main(String[] args) {
//		int[] scores = new int[] { 90, 88, 76, 66 };
		int[] scores = { 90, 88, 76, 66 };
		//错误
//		int[] scores;
//		scores = { 90, 88, 76, 66 };
		
        for (int score : scores) {
			System.out.println(score);
		}
	}

ArrayIndexOutOfBoundsException 下标越界异常

冒泡排序

	// 冒泡排序
	public static void main(String[] args) {
		// 小→大
		int[] arr = { 25, 16, 7, 51, 65, 78, 91, 1 };// 8个数
		for (int i = 0; i < arr.length - 1; i++) {
			for (int j = 0; j < arr.length - 1 - i; j++) {
				// 交换
				if (arr[j] > arr[j + 1]) {
					int temp = arr[j];
					arr[j] = arr[j + 1];
					arr[j + 1] = temp;
				}
			}
		}
		System.out.println(Arrays.toString(arr));
	}

数组排序:Arrays.sort(数组名);默认是正序排序

数组转字符串:Arrays.toString(数组名);

数组扩容/缩容:Arrays.copyOf(数组名 , 新长度);

扩容:新长度比原长度大

缩容:新长度比原长度小

数组克隆:数组名.clone();

Arrays.copyOf(数组名 , 原长度);

比较两个数组是否相等:Arrays.equals(num1,num2);

二分查找法:Arrays.binarySearch(); 前提是有序数组

public static void main(String[] args) {
//		int[] arr = { 15, 17, 28, 39, 40, 51, 57 };
//		Scanner sc = new Scanner(System.in);
//		int num = sc.nextInt();
//		boolean flag = false;
//		// 查找数组下标最小值
//		int min = 0;
//		// 查找数组下标最大值
//		int max = arr.length - 1;
//		// 当最小值小于等于最大值
//		while (min <= max) {
//			// 寻找中间值
//			int m = (min + max) / 2;
//			if (num == arr[m]) {
//				System.out.println("找到了");
//				flag = true;
//				break;
//			} else if (num > arr[m]) {
//				min = m + 1;
//			} else {
//				max = m - 1;
//			}
//		}
//		if(!flag) {
//			System.out.println("没有");
//		}

		/*
		 * 二分查找法:Arrays.binarySearch(),前提是有序数组
		 */
//		int[] arr = { 15, 17, 28, 39, 40, 51, 57 };
//		Scanner sc = new Scanner(System.in);
//		System.out.println("输入一个数:");
//		int n = sc.nextInt();
//		int index = Arrays.binarySearch(arr, n);
//		if (index >= 0 && index <= arr.length - 1) {
//			System.out.println("找到了");
//			System.out.println(index);
//		} else {
//			System.out.println("没有");
//		}

		Scanner sc = new Scanner(System.in);
		int[] nums = { 1, 5, 8, 2 };
		System.out.println("输入一个数:");
		int num = sc.nextInt();
		boolean flag = false;
		for (int i = 0; i < nums.length; i++) {
			if (num == nums[i]) {
				System.out.println("找到了");
				flag = true;
				break;
			}
		}
		if (!flag) {
			System.out.println("木有");
		}

	}

二维锯齿数组

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

int[] [] nums = new int[2] [3];

nums[0] [0] nums[0] [1] nums[0] [2]

nums[1] [0] nums[1] [1] nums[1] [2]

nums是一个数组,里面有2个元素,长度是2

nums[0]也是一个数组,里面有3个元素,长度是3

nums[1]也是一个数组,里面有3个元素,长度是3

public static void main(String[] args) {
//		int[][] nums = new int[2][3];
//		//第一行
//		nums[0][0] = 1;
//		nums[0][1] = 2;
//		nums[0][2] = 3;
//		//第二行
//		nums[1][0] = 4;
//		nums[1][1] = 5;
//		nums[1][2] = 6;
//		System.out.println(nums.length);
//		System.out.println(nums[0].length);
//		System.out.println(nums[1].length);
		
//		int[][] nums = new int[2][];
//		nums[0] = new int[3];
//		nums[1] = new int[2];
		
		int[][] nums = new int[][] {{1,2,3},{4,5,6,7}};
		int[][] nums2 = new int[][] {{1,2,3},{4,5,6,7}};
		
		//遍历数组
		for(int i=0; i < nums.length; i++) {
			for(int j=0; j < nums[i].length; j++) {
				System.out.print(nums[i][j] +  " ");
			}
			System.out.println();
		}
		
		System.out.println(Arrays.deepToString(nums));
		System.out.println(Arrays.deepEquals(nums, nums2));
	}

面向对象

面向过程:是具体化的,流程化的,解决一个问题,你需要一步一步的分析,一步一步的实现。

注重的是具体实现过程,每个步骤亲力亲为

例:吃饺子=》和面,和馅,包,蒸,吃...自己弄

面向对象:是模型化的,注重的对象与对象之间的协作,不必去一步一步的实现

例:点外卖,商家做,骑手送,自己吃

面向对象优点:

优点:易维护,易复用,易扩展

类:是一种抽象的表示,可以把具有相同特征的事物归为一类,例如:人类,车类,鸟类...

对象:类别中具体的一个事物

对象的成员:

1.属性:指对象的特征

2.方法:指对象的动作(行为)

定义类

访问修饰符 class 类名{

}

定义方法

访问修饰符 返回值类型 方法名(参数列表){
​
    方法体
    return 返回值;
}
​
1.无参数无返回值类型
​
访问修饰符 void 方法名(){
​
    方法体
​
}
​
2.有参数无返回值类型
​
访问修饰符 void 方法名(参数列表){
​
    方法体
​
}
​
3.无参数有返回值类型
​
访问修饰符 返回值类型 方法名(){
​
    方法体
    return 返回值;
}
​
4.有返回值类型有参数
​
访问修饰符 返回值类型 方法名(参数列表){
​
    方法体
    return 返回值;
}

 

参数列表:方法中需要数据时,但它本身没有,需要从外部传入,就要定义参数

形参:形式参数,在方法定义时写的参数

实参:实际参数,在方法调用时传入的参数

返回值:外部需要方法内部数据时,需要返回值

1.在定义方法时,需要指定返回值类型

2.在方法体中,使用return关键字,返回一个具体的值

重载的定义:

1、在同一个类中

2、方法名相同,参数列表不同

3、和返回值、访问修饰符没关系

方法重载:方法名相同,参数列表不同(参数的个数不同,参数类型不同)

方法签名:方法名+参数列表

可变长参数/不定长参数:数据类型... 变量名 注意:可变长参数必须是最后一个参数

成员变量(字段,域) 成员变量默认值: 整数类型:0 byte:(byte)0 short:(short)0 int:0 long:0L 浮点类型:0.0 float:0.0F double:0.0 字符类型:0 布尔类型:false 类类型:null

**成员变量和局部变量的区别:**
  	1.作用域不同:
  		局部变量的作用域仅局限于定义它的方法
  		成员变量的作用域在整个类内部都是可见的,还可以在外部访问
  	2.初始值不同:
  		Java会给成员变量一个初始值
  		Java不会给局部变量一个初始值
  	3.在同一个方法中,不允许有同名局部变量
  	   在不同的方法中,可以有同名局部变量
  	4.两类变量同名时,局部变量具有更高的优先级

 

面向对象三大特征:封装,继承,多态

值传递和引用传递

1、基本数据类型:

基本数据类型作为形式参数,形参的改变不会影响实际参数,传递的是值本身

public class Demo {
	public static void main(String[] args) {
		Dome d = new Dome();
		int x = 10;
		System.out.println("前:"+x);
		d.memo(x);
		System.out.println("后:"+x);
	}
}

class Dome{
	public void memo(int x) {
		x += 5;
		System.out.println("哦:"+x);
	}
}
结果为:
前:10
哦:15
后:10

2、引用数据类型:

引用数据类型作为参数,形参的改变改变影响实际参数,传递的是地址值

public class Demo {
	public static void main(String[] args) {
		Student d = new Student();
		d.name = "小明";
		d.age = 22;
		System.out.println("前" + d.name + d.age);
		
		Dome t = new Dome();
		t.memo(d);
		System.out.println("后"+d.name + d.age);
	}
}

class Dome{
	public void memo(Student x) {
		x.name = "小张";
		x.age = 18;
		System.out.println("1:"+x.name + x.age);
	}
}

class Student{
	String name;
	int age;
}
结果:
前:小明22
1:小张18
后:小张18

匿名对象:

new	对象名();
new 对象名().方法名(new 对象名());

特点:对象只会被调用一次

 

封装(private)

1.定义一个方法是一种封装

2.成员变量或者方法用private修饰是一种封装

属性组成部分:属性变量和属性访问器

属性变量:用于表示属性的成员变量

属性访问器:setter和getter

属性名:setter和getter去掉set和get后,剩下部分首字母小写

只读属性:只有getter没有setter

public class Student {
	private int score;
	// 赋值方法 setter (set访问器)
	public void setScore(int score) {
		//this:本类对象
		this.score = score;
	}

	// 取值方法 getter (get访问器)
	public int getScore() {
		return score;
	}
}

什么情况下封装: 1、保护字段/数据,这个字段/数据我不想让外界用户知道,就使用封装 2、但是可以让外部修改它,这个时候就使用到封装(属性封装) 3、这个字段/数据我要限制用户输入的值,比如说这个字段是sex性别,只能输入男和女,超出了这个范围 就没有 数据,所以我们要限制用户输入的内容,这个时候就使用封装 4、就是只提供这个数据可以给用户外界使用,但不能修改它,此时就用到的封装

构造器(构造方法)

没有返回值,名称和类名相同

构造方法是在实例化对象时自动调用

默认构造方法:

1.如果不创建构造方法,也有一个默认构造方法

2.默认构造方法没有参数

3.如果创建了有参构造方法,则默认构造方法消失

在构造器中调用本类其他构造器:this(参数)

this()必须写在构造器的第一行代码上

无参构造:

访问修饰符 类名(){
    
}

有参构造:

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

一个基本的类应该具备以下特点:

1、成员变量

2、构造方法(有、无参数)

3、成员方法(get/set方法)

 

静态方法(类方法)

是属于类的,不属于对象,使用类调用

静态方法不能直接调用成员方法,也不能直接使用成员变量

访问静态成员的方法:

类名.成员变量

类名.成员方法

静态方法不能使用this和super

成员方法可以调用静态方法,也可以使用静态变量

static能够修饰的成员有:成员变量、成员方法、修改类、内部类

开发工具类时经常使用static

静态块/静态代码块

static{}

在第一次使用类的时候自动调用,而且只调用一次

静态块的执行要优先于主方法的执行

一般用于初始化静态成员变量

静态块和静态方法的区别:

1.静态块自动调用,静态方法手动调用

2.静态块只调用一次,静态方法可以调用多次

3.静态块没有访问修饰符,返回值类型,名称,参数,静态方法有

动态块:{},实例化对象时自动调用,可以执行多次

1、局部代码宽:定义在局部位置, 作用是限定局部局部变量的作用域

2、构造代码块:定义在类的成员变量的位置,用来抽取多个构造方法重复的代码,做成员变量的初始化

执行顺序:静态代码块 > 动态代码块 > 构造方法

JVM内存:

栈,堆,方法区

栈:

栈帧:JVM为每一个方法都定义一个栈帧,栈帧中存放局部变量

堆:实例化出来的对象,成员变量

方法区:静态变量,方法信息

 

 

继承

减少代码冗余,实现代码重用性

访问修饰符 class 子类 extends 父类{

}

子类又叫派生类

父类又叫超类,基类

单继承:子类只能继承一个父类,如Java

多继承:子类可以继承多个父类,如C++

子类可以继承父类非私有成员(同包)

继承中的构造器:

1.先调用父类构造器,再调用子类构造器

2.子类默认调用父类的无参构造器

3.构造器不能继承

4.子类调用父类构造器:super(参数),super()必须写在构造器的第一行代码上

5.如果父类没有无参构造器,则子类必须手动调用父类的其他构造器

super:父类的

super.属性 父类的属性

super.方法(参数) 父类的方法

super(参数列表) 父类的构造方法,必须放在第一行

this:本类对象

this.属性 当前对象属性

this.方法() 当前对象的方法

this(参数列表) 当前构造方法,必须放在在、第一行

 

【访问修饰符】

  本类 本包其他类 其他包子类 其他包
public 共有的
protected保护的  
默认的(default)    
private私有的      

 

重写(覆盖):子类重新写父类的方法

一大两小两相同:

两相同:方法名相同,参数列表相同

一大:访问修饰符要大于等于父类的

两小:1)返回值类型要小于等于父类, 如果是基本类型或者void,必须保持一致

2)抛出异常的类型要小于等于父类的

不能重写的方法:

构造器不能重写

私有方法不能重写

静态方法不能重写

final修饰的方法不能重写

重写的特性:

必须存在继承关系

方法名必须相同

在子类中返回值不能改变

之类的方法修饰符要大于等于父类

@Override:表示重写

重写和重载的不同点及相同点:

重载和重写 重写(override) 重载(overload)
作用域 子重写父的 是同一作用域(子重载父的,重载自己)
方法名 必须一致 必须一致
参数列表 必须一致 必须不一致(个数不同,类型不同)
返回值类型 返回值类型要小于等于父类的,如果是基本类型或者void,必须保持一致 无所谓
访问修饰符 子大于等于父类 无所谓
异常 抛出异常的类型要小于等于父类的 无所谓
次数 一次 多次

 

多态

多态:父类的引用指向了子类的实例,同一种行为,产生的结果不同

满足多态的条件:继承,重写,向上造型

面向对象三大特征:封装,继承,多态

面向对象四大特征:封装,继承,多态,抽象

父类 变量名1 = new 子类1();
父类 变量名2 = new 子类2();
父类 类变量名3 = new 子类3();
变量名1.方法名();
变量名2.方法名();
变量名3.方法名();

同一个引用类型,使用不同的实例执行不同的操作,即父类引用指向了子类对象

多态的应用:

1、使用一个父类作为一个方法的形参,如果一个父类作为参数,可以传入父类对象,也可以传入子类对象

2、使用父类作为一个方法的返回值,(抽象类)传入的是子类对象,(接口)返回的是实现类对象

public static void main(String[] args){
    父类 变量名 = new 父类();
    变量名.方法名(变量名1,变量名2,...);
}
public class 父类名(){
  public void 方法名(子类名1 变量名1,子类名2 变量名2,...){
    变量名1.子类方法名1();
    变量名2.子类方法名2();
}  
}

链式调用:当方法的返回值类型是引用数据类型的时候,可以使用链式调用

父类名 变量名 = 父类变量名.方法名1().方法名2(),...;

在多态中不能直接调用子类特有的方法,只能通过强制转化实现

多态中的强制转换:

向上造型(向上转型)(自动转换):子类型赋值给父类型

父类型 变量名 = new 子类名();

向下造型(强制转换):父类型赋值给子类型(会出现类型转换异常)

子类名 变量名 = (子类名)父类变量名;

补充

instanceof:判断左边的对象是否是右边的实例,结果是boolean,是返回true,不是返回false,通常和向下造型(强制转换)结合使用

if(父类变量名 instanceof 子类名){
	子类名 变量名 = (子类名)父类变量名;
}

包:主要是用来对类进行整理的,将同种类型的类放在同一个包中。com.zretc.javase.d0831

声明包语法:package 包名; 只能有一条,且必须放在有效代码第一行,注释除外

导包:当使用的类不在同一个包中时,需要导包

导包的语法:import 包名.类名; 导包可以有多条,且必须放在声明包下面,定义类上面

单类导入:import 包名.类名;

多类导入:import 包名.*;

可以直接使用的包:Java.lang

final

final:最终,不可变的,可以修饰类、变量和方法

final修饰类,不能被继承

final修饰方法,不能被重写

对于方法和类,abstract和final不能连用

常量:用final修饰常量。只有一次赋值机会,之后都不能改变,常量一般声明为static,命名规范:所有字母都大写,每个单词之间用下划线隔开(尖叫式蛇底命名法)

final修饰成员变量,在定义时必须赋值,也可以在构造器和动态块中赋值

final修饰局部变量,可以在使用前赋值

对于基本类型来说,变量中的数据不可改变

对于引用类型来说,变量中的地址值不可改变

final修饰参数,不可以赋值,值是通过方法调用传过来的,在方法内部不能改值

抽象

抽象类:类上用abstract修饰

abstract class 类名{}

抽象方法:方法上用abstract修饰,没有方法体

abstract 返回值类型 方法名();

抽象类不能实例化对象,可以使用多态方法赋值

抽象类可以有抽象方法,也可以有非抽象方法;但抽象方法中必须有抽象类

如果子类不是抽象类,则必须实现父类的抽象方法

如果子类也是抽象类,则可以不实现父类的抽象方法

抽象类中可以包含:成员变量、成员方法、常量、构造方法、静态方法、代码块、静态代码块,所以抽象类是一个用给子类服务的类,抽象方法是个子类重写的方法

static、private、final(即不能被重写的方法)不能和abstract连用

如:
public static abstract void sum();

 

接口

是一种公共的规范标准,引用数据类型,由常量和抽象方法组成

定义接口:

访问修饰符 interface 接口名{
	常量;
    抽象方法;
}

1.在默认情况下,接口中的方法都是公有抽象方法(public abstract)

public abstract 返回值类型 方法名();//abstract可以省略不写

2.接口不能实例化对象,需要通过实现类(implements)来实现

3.接口中没有构造器

4.接口中的变量,都是公有静态常量(public static final修饰)

public static final 数据类型 变量名;//static final可以省略不写

5.在Java8中,提供了接口的默认方法(default)和静态方法

default 返回值类型 方法名(){}
访问修饰符 static 返回值类型 方法名(){}

6.在Java9中,提供了接口的私有方法(private)

7.定义一个实现接口的语法:implements实现

访问修饰符 class 类名 implements 接口名1,接口2,...{
    
	} 

8.定义一个接口继承接口的语法:extends继承

访问修饰符 interface 接口名 extends 接口1,接口2...{

	}

9.在Java中,类是单继承,接口是多实现,多继承。

10.实现类既可以继承父类,又可以实现接口

访问修饰符 class 类名 extends 父类 implements 接口名1,接口名2,...{

	}

类与接口的关系:

类和类:单继承,不可以实现

类和接口:单继承,多实现

接口和接口:多继承,不可以多实现

11.抽象类和接口

  抽象类 接口
定义关键字 abstract class interface
继承关系 单继承 多继承
构造方法
实例化对象 不能 不能
普通成员 可以 不能有变量,普通方法是jdk1.8之后可以
与接口的关系 多实现【implements】 多继承【extends】

内部类

内部类不能被外界直接实例化,但可以直接访问外部类的所有的成员变量和方法

静态内部类,动态内部类,成员/局部内部类,匿名内部类

静态内部类

访问修饰符 class 外部类{

	访问修饰符 static class 内部类{

	}

}
public class Outer {
	private static int n = 1;
	public static class Inner {
		private int n = 2;
		public void show() {
			int n = 3;
			System.out.println(Outer.n + "," + this.n + "," + n);
		}
	}

	public void display() {
		Inner inner = new Inner();
		inner.show();
	}

}

在外部访问静态内部类: 外部类.内部类 变量 = new 外部类.内部类();

		Outer.Inner inner = new Outer.Inner();
		inner.show();

动态内部类

访问修饰符 class 外部类{

	class 内部类{

	}

}
public class Outer {
    private int n = 1;
​
    public class Inner {
        private int n = 2;
​
        public void show() {
            int n = 3;
            System.out.println(Outer.this.n + "," + this.n + "," + n);
        }
    }
​
    public void display() {
        Inner inner = new Inner();
        inner.show();
    }
​
}

在外部访问动态内部类

外部类 变量 = new 外部类();

外部类.内部类 变量 = 外部类变量.new 内部类();

获取静态内部类中的静态方法或属性:

外部类.内部类.静态方法();

外部类.内部类.静态变量;

        Outer outer = new Outer();
        Outer.Inner inner = outer.new Inner();
        inner.show();

当外部类和内部类成员变量同名时:获取外部类成员变量的方式:外部类.this.变量名

局部内部类

public class Demo {
	
	public static void main(String[] args) {
		//局部内部类
		class Inner{
			public void show() {
				System.out.println("show");
			}
		}
		Inner inner = new Inner();
		inner.show();
	}

}

匿名内部类

public static void main(String[] args) {
		/*
		 * 	匿名内部类
		 * 	类名 变量 = new 类名(){};
		 */
		Human h = new Human() {

			@Override
			public void work() {
				System.out.println("工作");
			}
			
		};
		
		h.work();
	}

类能用什么访问修饰符修饰

1.对于外部类,只能用public和默认

2.对于内部类:

1)如果是静态内部类和动态内部类:四种都可以

2)如果是局部内部类和匿名内部类:不可以写

常用类

String字符串

java.lang.String 包下

程序中所有的双引号字符串,都是String类的对象(就算没有new,也是)

charAt():依据索引查找字符

compareTo():字符串比较,正数:第一个串大,负数:第二个串大,0:相等

compareToIgnoreCase():不区分大小写比较,正数:第一个串大,负数:第二个串大,0:相等

concat():拼接字符串

contains():判断是否存在

startsWith():判断是否以某子串开头

endsWith():判断是否以某子串结尾

equals():判断字符串相等

equalsIgnoreCase():不区分大小写判断字符串相等

getBytes():将字符串转成字节数组

indexOf():依据元素查找索引(第一次出现)

lastIndexOf():依据元素查找索引(最后一次出现)

isEmpty():判断是否是空串

length():字符串长度

replace():字符串替换

split():字符串分割,返回值类型为字符串数组。注意:如果遇到分割时出现错误,需要将分隔符用\转义

substring():截取子串,不包含结束位置,含头不含尾。字符串.substring(开始位置),从开始位置截取 到最后

toCharArray():字符串转char类型数组

toLowerCase():转成小写

toUpperCase():转成大写

trim():去掉左右两边空格

字符串常量池

字符串常量池:程序中直接写上的双引号字符串,就在字符串常量池中

对于基本数据类型,==是进行数值的比较

对于引用数据类型,==是进行地址的比较

地址相同的情况: 情况1: String str1 = "abc"; String str2 = "abc"; 情况2: String s1 = "abc"; String s2 = "ab" + "c"; 地址不相同的情况: 情况1: String s1 = "abc"; String s = "c"; String s2 = "ab" + s; 情况2: String ss1 = new String("abc"); String ss2 = new String("abc");

StringBuilder,StringBuffer

专门用于字符串拼接的,拼接时不生成新的对象,拼接速度快

String,StringBuilder,StringBuffer的区别:

1.String是常量,值不能改变,拼接字符串时生成新的对象,拼接速度慢

StringBuilder,StringBuffer是动态拼接,拼接时不生成新的对象,拼接速度快

2.StringBuider,StringBuffer提供了更多的方法,如插入,删除

3.StringBuilder是线程不安全的,拼接速度快

StringBuffer是线程安全的,拼接速度慢

	public static void main(String[] args) {
		StringBuilder s = new StringBuilder();
		//添加字符串
		s.append("ab");
		s.append("hello");
		System.out.println(s);
		// 插入字符串
		s.insert(1, "q");
		System.out.println(s);
		// 删除字符串,含头不含尾
		s.delete(1, 4);
		System.out.println(s);
		
		StringBuilder s2 = new StringBuilder("abcd");
		//字符串反转
		System.out.println(s2.reverse());
	}

包装类型

包装类型:每一个基本类型,都对应着一个类,他将基本类型封装到类中,添加了额外的功能,还可以赋值为null

基本类型 包装类型 父类型
byte Byte Number
short Short Number
int Integer Number
long Long Number
float Float Number
double Double Number
char Character Object
boolean Boolean Object

装箱:基本类型转换成包装类型的过程

拆箱:包装类型转换成基本类型的过程 【手动拆装箱】 Java 5之前 手动装箱:将基本类型写在包装类型的构造器中。Integer a1 = new Integer(200); 手动拆箱:包装类型变量.xxxValue(); int a2 = a1.intValue(); 【自动拆装箱】 自动装箱:包装类型 变量 = 基本类型值; Integer num = 200; 自动拆箱:基本类型 变量 = 包装类型变量 【自动拆装箱的注意事项】 赋值时,要求严格对应上类型。如: Long a = 10L; Double b = 2D;

 	包装类型比较用equals方法
 	
 	【整型池】
 	整型缓存池,整型常量池
 	范围:-128~127
 
 	Integer i1 = 128;
 	Integer i2 = 128;
 	System.out.println(i1 >= i2);//true
 	首先将两个包装类型自动拆箱成基本类型,然后比较基本类型的值
 
 	类型转换:
 	包装类型.parse类型(字符串); 返回基本类型
 	包装类型.value Of(字符串);  返回包装类型
 	
 	最大值:MAX_VALUE
 	最小值:MIN_VALUE
 	位数:SIZE

DoubelTest

NaN:Not a Number NaN和任何一个数都不相等,包括它自己 Double.isNaN(数值):判断是否是NaN Double.NaN:0.0d / 0.0 Infinity:正无穷 -Infinity:负无穷 Double.POSITIVE_INFINITY:1.0 / 0.0 Double.NEGATIVE_INFINITY:-1.0 / 0.0

CharacterTest

	public static void main(String[] args) {
		char c = ' ';
		// 判断是否是整数
		System.out.println(c >= '0' && c <= '9');
		System.out.println(Character.isDigit(c));
		// 判断是否是小写字母
		System.out.println(c >= 'a' && c <= 'z');
		System.out.println(Character.isLowerCase(c));
		// 判断是否是大写字母
		System.out.println(c >= 'A' && c <= 'Z');
		System.out.println(Character.isUpperCase(c));
		// 判断是否是字母
		System.out.println((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'));
		System.out.println(Character.isLetter(c));
		// 判断是否字母或数字
		System.out.println((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')||(c >= '0' && c <= '9'));
		System.out.println(Character.isLetterOrDigit(c));
		//判断是否是空白字符(空格,Tab,回车,换行)
		System.out.println(Character.isWhitespace(c));
	}

正则表达式

Java是从Java1.4开始支持正则表达式

正则表达式,简写为regex,regexp,regxp等

是用于匹配、查找、替换文本等操作的表达式

正则表达式包含普通字符和元字符

元字符就是一类特殊字符,有具体的含义:

^、$:开始和结束

[abc]:匹配abc中任意字符

[ ^abc]:除了abc的任意字符

[a-z]:a到z之间的字符

[a-zA-Z0-9]:a到z、A到Z、0到9之间的任意字符

\d :数字字符,等效于[0-9]

\w :单词字符,等效于[ a-zA-Z0-9_ ]

\s :空白字符,如空格,制表符,换行,回车等。

\D :非数字字符

\W:非单词字符

\S :非空白字符

?:0到1个

*:0到多个

+:1到多个

.:任意字符

|:或者

\:转译

X{n}:n个X

X{n,}:n到多个X

X{n,m}:n到m个X

^:非

():分组

1、字符串查找操作:Pattern和Matcher

2、字符串匹配操作:可以通过字符串matchers方法

3、字符串替换操作:replaceAll()和replaceFirst()方法

4、字符串的分割:字符串的split()方法

	public static void main(String[] args) {
		String str = "中国";
		//验证是否是整数
		boolean ok = str.matches("^\\d+$");
		System.out.println(ok);
		//验证是否是小数
		boolean ok2 = str.matches("^\\d+\\.\\d+$");
		System.out.println(ok2);
		//验证两位小数
		boolean ok3 = str.matches("^\\d+\\.\\d{2}$");
		System.out.println(ok3);
		//验证整数或者小数
		boolean ok4 = str.matches("^\\d+(\\.\\d+)?$");
		System.out.println(ok4);
		//验证大多数汉字:\u4E00 \u9FA5
		boolean ok5 = str.matches("^[\u4E00-\u9FA5]+$");
		System.out.println(ok5);
		
	}
	public static void main(String[] args) {
		String str = "abc123def456wer";
		//str = str.replace("123", "-");
		str = str.replaceAll("\\d+", "-");
		System.out.println(str);
		
		String str2 = "Java.Python.PHP";
		String[] ss = str2.split("\\.");
		System.out.println(Arrays.toString(ss));
	}
	public static void main(String[] args) {
//		String str = "Java123Python456";
//		// 模式对象,设置正则表达式
//		Pattern p = Pattern.compile("[a-zA-Z]+");
//		// 匹配对象,匹配字符串
//		Matcher m = p.matcher(str);
//		// 判断有没有找到匹配上的字符串
//		while(m.find()) {
//			System.out.println(m.group());//匹配上的字符串
//		}
		
		String str = "name=tom;salary=¥$18000;";
		Pattern p = Pattern.compile("(\\w+)=([^;]+)");
		Matcher m = p.matcher(str);
		while (m.find()) {
			//m.group(组索引),从1开始
			System.out.println(m.group(1) + "\t" + m.group(2));
		}

Object

Object是所有类的父类,又叫顶级父类,也叫万类之源

如果一个类没有指定父类,默认继承了Object

除了Object之外,剩下的所有类都有父类

Object中有一些方法,有时需要重写

如:toString(),默认是返回类全名@哈希值

一般用作返回类中信息(成员变量的值),所以需要重写

toString方法的功能是返回字符串形式

对于print和println,如果传入了类类型变量,就是调用了toString方法

equals(),equals方法是Object中的方法,默认是判断地址相等(==)

但是建议你重写equals(),用于比较值相对

(比如String,在String类中定义了equals能够比较值相对,是因为String中重写了equals方法)

@Override
	public boolean equals(Object obj) {
		//当方法的形参是引用数据类型时,建议做非空处理
		if(obj==null) {
			return false;
		}
		//判断是不是同一个类型
		if(obj instanceof Demo2) {
			//比较具体属性,Object向下转型
			Demo2 d = (Demo2) obj;
			//判断name和age是否相同
			if(this.name.equals(d.getName()) && d.getAge() == d.getAge()) {
				return true;
			}
		}
		return false;
	}

 

Math

Math.max():最大值

Math.min():最小值

Math.round():四舍五入

Math.ceil():向上取整

Math.floor():向下取整

Math.pow():求幂

Math.sqrt():开平方

Math.cbrt():开立方

Math.abs():绝对值

Math.PI():π

日期类

date

Date date = new Date();

调用了System.currentTimeMillis()

Date date = new Date(毫秒数);传入系统毫秒数

date.getTime():获取系统毫秒数

date.setTime():设置系统毫秒数

date2.compareTo(date):日期比较,返回值:正数:第一个日期大,负数:第二个日期大,0:相同

date2.after(date):判断日期是否是另一个日期之后

date2.before(date):判断日期是否是另一个日期之前

SimpleDateFormat,简单日期格式,用来做日期的格式化

格式化字符:

y:年(yyyy:四位年及以上;yy:两位年)

M:月(MM:两位月)

d:日(dd:两位日期)

h:12进制小时(hh:两位小时)

H:24进制小时(HH:两位小时)

m:分钟

s:秒

S:毫秒

E:星期

a:上午/下午

X,Z:时区

如果想要直接显示字母,需要加上单引号

	public static void main(String[] args){
		Date date = new Date();
		// System.out.println(date);
		// 如果向直接显示字母,需要加上单引号
		SimpleDateFormat fmt = new SimpleDateFormat("yyyy年MM月dd日  'at' HH:mm:ss:SS");
		// Date对象转格式化字符串
		String str = fmt.format(date);
		System.out.println(str);
		// 格式化字符串转Date对象,字符串和日期格式不一致时,日期转换异常:ParseException
		//Date date2 = fmt.parse(str);
		Date date2 = fmt.parse(str, new ParsePosition(0));
		System.out.println(date2);

	}

Calendar

格里高利历(公历,阳历,GregorianCalendar)

获取年份:cal.get(Calendar.YEAR)

获取月份,月份从0开始,所以真实月份需要加1:cal.get(Calendar.MONTH)+1

获取日期:cal.get(Calendar.DATE)

cal.get(Calendar.DAY_OF_MONTH)

获取小时(12进制):cal.get(Calendar.HOUR)

获取小时(24进制):cal.get(Calendar.HOUR_OF_DAY)

获取分钟:cal.get(Calendar.MINUTE)

获取秒:cal.get(Calendar.SECOND)

获取毫秒:cal.get(Calendar.MILLISECOND)

获取星期,星期从1开始,星期日是1,所以需要减1:cal.get(Calendar.DAY_OF_WEEK) - 1

	public static void main(String[] args) {
		Calendar cal = Calendar.getInstance();
		System.out.println(cal);
//		System.out.println(cal.getClass());
//		Calendar cal2 = new GregorianCalendar();
//		System.out.println(cal2);
		// 获取年份:
		System.out.println(cal.get(Calendar.YEAR));
		// 获取月份:月份从0开始,所以真实月份需要加1
		System.out.println(cal.get(Calendar.MONTH) + 1);
		// 获取日期
		System.out.println(cal.get(Calendar.DATE));
		System.out.println(cal.get(Calendar.DAY_OF_MONTH));
		// 获取小时(12进制)
		System.out.println(cal.get(Calendar.HOUR));
		// 获取小时(24进制)
		System.out.println(cal.get(Calendar.HOUR_OF_DAY));
		// 获取分钟
		System.out.println(cal.get(Calendar.MINUTE));
		// 获取秒
		System.out.println(cal.get(Calendar.SECOND));
		// 获取毫秒
		System.out.println(cal.get(Calendar.MILLISECOND));
		// 获取星期,星期从1开始,星期日是1,所以需要减1
		System.out.println(cal.get(Calendar.DAY_OF_WEEK) - 1);

	}

 

	public static void main(String[] args) {
		Calendar cal = Calendar.getInstance();
		//获取Date对象
		Date date = cal.getTime();
		SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
		System.out.println(fmt.format(date));
		
		Calendar cal2 = Calendar.getInstance();
		// 将date对象传到Calendar中
		cal2.setTime(date);
		System.out.println(cal.get(Calendar.YEAR));
		
		
		// 获取系统毫秒数
		System.out.println(cal.getTimeInMillis());
		// 设置系统毫秒数
		cal.setTimeInMillis(123456L);
	}

设置字段:cal.set(字段常量,值);

设置年:cal.set(Calendar.YEAR, 2018);

设置月:cal.set(Calendar.MONTH, 10-1);

设置日期:cal.set(Calendar.DATE, 30);

设置年月日:cal.set(2017, 10-1, 30);

添加字段的值:cal.add(字段的常量, 值)

滚动字段的值:cal.roll(字段的常量, 值)

add和roll的区别:

add:如果超出本字段的范围,会影响到上一个字段

roll :如果超出本字段的范围,不会影响到上一个字段,

会在本字段中循环滚动

获取最大值:cal.getActualMaximum()

获取最大值:cal.getMaximum()

getActualMaximum和getMaximum的区别:

getActualMaximum跟当前字段的值有关

getMaximum跟当前字段的值无关,只是获取本字段的最大值

当前日期是当前年份的第几天:cal.get(Calendar.DAY_OF_YEAR);

 

泛型

泛型:参数化的类型

泛型:泛型方法,泛型类

泛型:不支持基本类型,不能实例化对象

Java中的泛型,是Java5增加的特征

擦除法泛型,Java的泛型是语法层面的,编译之后,泛型类型是Object

在Java7 之前:类名<泛型类型> 变量 = new 类名<泛型类型> ();

在Java7 及之后版本:类名<泛型类型> 变量 = new 类名<> ();

泛型:只能是类类型的,可以把类类型当成参数来传递

泛型方法:

访问修饰符 < T> 返回值类型 方法名(参数列表){}

public class MyArrayUtil {

	public static <T> T[] add(T[] arr, T value) {
		arr = Arrays.copyOf(arr, arr.length + 1);
		arr[arr.length - 1] = value;
		return arr;
	}
	
	public static Object add2(Object[] nums,Object value) {
		nums = Arrays.copyOf(nums, nums.length+1);
		nums[nums.length-1] = value;
		return nums;
	}

}

泛型类:

访问符 class 类名< T>{}

泛型限定:

访问修饰符 class 类名<T extends 父类>{}

public class MyArrayUtil02<T extends Number> {
	
	Object[] nums = new Object[0];
	
	public void add(T value) {
		nums = Arrays.copyOf(nums, nums.length + 1);
		nums[nums.length - 1] = value;
	}

	@Override
	public String toString() {
		return Arrays.toString(nums);
	}

}
	public static void main(String[] args) {
		MyArrayUtil02<Integer> myArray = new MyArrayUtil02<>();
		myArray.add(10);
		myArray.add(20);
		System.out.println(myArray);
	}

泛型的好处:

1、提高程序的安全性

2、消除黄色警告

3、在编译时期将类型确定,减少了不必要的强转代码

集合

List是Collection的子接口,主要存储有序可重复数据

ArrayList:数组列表,使用数组实现

添加元素:list.add();

插入元素:list.add(索引,元素);

修改元素:list.set(索引,元素);

删除元素(依据元素删除):list.remove(元素);

删除元素(依据索引删除):list.remove(索引);

如果泛型类型是Integer,使用remove时,传入元素,会当成索引,所以需要将元素强制转换成Integer或Object。

获取元素:list.get(索引);

集合长度:list.size();

清空集合:list.clear();

遍历集合三种方式:

	public static void main(String[] args) {
		List<Integer> list = new ArrayList<>();
		list.add(3306);
		list.add(1433);
		list.add(1521);
		// 遍历集合 
		// 方式一,使用普通for循环
		for(int i=0;i<list.size();i++) {
			System.out.println(list.get(i));
		}
		System.out.println("===============");
		// 方式二,使用增强for循环
		for(Integer a : list) {
			System.out.println(a);
		}
        System.out.println("==============");
		// 方式三,使用迭代器
		// 获取迭代器
		Iterator<Integer> it = list.iterator();
		// 判断有没有下一条数据
		while(it.hasNext()) {
			// 移动到下一条,并获取数据
			System.out.println(it.next());
		}
	}

Collections:集合工具类

Collections.addAll(集合,元素,元素,...):向集合中添加若干元素

判断是否有某子串:list.contains()

依据元素查找索引(从左到右):list.indexOf()

依据元素查找索引(从右向左):list.lastIndexOf()

判断集合是否为空:list.isEmpty()

获取子集合(含头不含尾):

实际上是从集合中获取一部分,但是还是同一个集合,一个修改,会影响另一个

如果想互不影响,需要将list.subList()放到List集合的实现类的构造器里

List<Integer> sub = new ArrayList<>(list.subList(1, 3));

Collection和Collections的区别

Collection是集合的总接口,是存储单一类型的集合

Collections是集合工具类,提供操作集合的相关方法

数组转List:

Arrays.asList():转成了只读集合

正确做法:将Arrays.asList()放在List实现类的构造器里

List<泛型类型> 变量 = new ArrayList<>(Arrays.asList(数组));

		Integer[] nums = { 1, 2, 3 };
		List<Integer> list = new ArrayList<>(Arrays.asList(nums));
		list.add(0, 10);
		System.out.println(list);

List转数组:

方式一:类型[] 数组 = list.toArray(new 类型[0])

方式二:类型[] 数组 = new 类型[集合长度]

list.toArray(数组)

		// 方式一
		// Integer[] arr = list.toArray(new Integer[0]);
		// 方式二
		Integer[] arr = new Integer[list.size()];
		list.toArray(arr);
		// 输出arr数组
		System.out.println(Arrays.toString(arr));

集合排序

	public static void main(String[] args) {
		List<Integer> list = new ArrayList<>();
		Collections.addAll(list, 3306, 1433, 1521);
		// 正序排序
		// Collections.sort(list);
		
		/*
		 * 	正序排序:第一个数减第二个数
		 * 	叙排序:第二个数减第一个数
		 */
		
//		Collections.sort(list, new Comparator<Integer>() {
//
//			@Override
//			public int compare(Integer o1, Integer o2) {
//				return o2 - o1;
//			}
//			
//		});
//		
//		System.out.println(list);
		
		list.sort(new Comparator<Integer>() {

			@Override
			public int compare(Integer o1, Integer o2) {
				return o1 - o2;
			}
		});
		System.out.println(list);
		
	}

 

ArrayList和LinkedList的区别:

  1. ArrayList是用数组实现的,在内存中是连续的,适合遍历和追加

  2. LinkedList是用链表实现的,在内存中不是连续的,适合插入和删除

    LinkedList能够实现队列和栈

    队列:先进先出(FIFO)

    栈:先进后出(FILO)

Queue<类型> queue = new LinkedList<>();

添加元素:queue.offer();

获取元素(不删除):queue.peek();

获取元素并删除:queue.poll();

	public static void main(String[] args) {
		Queue<Integer> queue = new LinkedList<>();
		// 添加元素
		queue.offer(10);
		queue.offer(20);
		queue.offer(30);
		System.out.println(queue);
		// 获取元素(不删除)
		System.out.println(queue.peek());
		System.out.println(queue.peek());
		System.out.println("==============");
		for (Integer num : queue) {
			System.out.println(num);
		}
		System.out.println("==============");
		// 获取元素并删除
		System.out.println(queue.poll());
		System.out.println(queue.poll());
		System.out.println(queue.poll());
   }
		

Deque<类型> stack = new LinkedList<>();

进栈:stack.push();

出栈:stack.pop():

	public static void main(String[] args) {
		Deque<Integer> stack = new LinkedList<>();
		// 进栈
		stack.push(10);
		stack.push(20);
		stack.push(30);
		System.out.println(stack);
		System.out.println("============");
		for (Integer n : stack) {
			System.out.println(n);
		}
		System.out.println("============");
		while(stack.size()>0) {
			System.out.println(stack.pop());
		}
		System.out.println("============");
		// 出栈
//		System.out.println(stack.pop());
//		System.out.println(stack.pop());
//		System.out.println(stack.pop());
	}

Set是Collection的子接口,无序存储,不可重复存储,可以存储null值

HashSet:无序的

添加元素:add()

依据元素删除:remove(元素)

获取长度:size()

遍历Set集合

		for (String string : phone) {
			System.out.println(string);
		}

Set集合转成List集合,放到List实现类的构造器中

List集合转Set集合,放到Set集合实现类的构造器中

	public static void main(String[] args) {
		Set<String> phone = new HashSet<>();
		phone.add("13312345688");
		phone.add("13912345688");
		phone.add("13612345688");
		// Set转成List,放到List实现类的构造器中
		List<String> list = new ArrayList<>(phone);
		list.add(1,"12212345678");
		list.add("13612345688");
		System.out.println(list);
		
		// List转Set,放到Set集合实现类的构造器中
		Set<String> set = new HashSet<>(list);
		System.out.println(set);
	}

HashSet:无序的

LinkedHashSet:添加的顺序

TreeSet:排序的(默认按照正序排序)

	public static void main(String[] args) {
		// 倒叙排序,将比较器放在TreeSet的构造器中
		Set<String>  phone = new TreeSet<>(new Comparator<String>() {

			@Override
			public int compare(String o1, String o2) {
				return o2.compareTo(o1);
			}
		});
		phone.add("13312345688");
		phone.add("13912345688");
		phone.add("13612345688");
		System.out.println(phone);
	}

Map以键值对的形式存在,键是不能重复的,值是可以重复的

HashMap:无序的

LinkedHashMap:添加的顺序

TreeMap:排序的(默认按照键的正序排序)

添加:put(键,值)

修改:put()

删除(依据键删除):remove(键)

是否包含某键:containsKey()

获取集合长度:size()

获取键集合:keySet()

获取值集合:values()

依据键获取值:get(键)

清空集合:clear()

遍历Map集合:

    public static void main(String[] args) {
        Map<String, String> map = new HashMap<>();
        map.put("name", "高斯林");
        map.put("gender", "男");
        map.put("job", "构架师");
​
        // 遍历Map集合方式一:通过遍历键集合
        for (String str : map.keySet()) {
            System.out.println(str + "\t" + map.get(str));
        }
        
        System.out.println("================");
        /*
         *  遍历Map集合方式二:通过遍历键值对对象
         *  Entry:键值对对象
         *  entry.getKey():获取键
         *  entry.getValue():获取值
         */
        for (Entry<String, String> entry : map.entrySet()) {
            System.out.println(entry.getKey() + "\t" + entry.getValue());
        }
        // 遍历值
        System.out.println("===========");
        for (String string : map.values()) {
            System.out.println(string);
        }
    }

Properties属性集合,键值对都是字符串,可以保持到文件中

添加值:setProperty(键,值)

获取值:getProperty(键)

获取值,如果没有键,就返回默认值:getPropertity(键,默认值);

HashMap和Hashtable的区别

1.HashMap是线程不安全的,速度稍快,推荐使用,赋值可以存放null

2.Hashtable是线程安全的,速度稍慢,不推荐使用,键值不能存放null

异常

异常的应用场景:

捕捉异常:当前行为发生异常后,还能找其他方案解决时用捕捉异常

抛出异常:当前行为发生异常后,不能找其他方案解决时用抛出异常

语法:

try-catch, try-catch-finally,try-finally

【try-catch】

try{

	//可能会出现异常的代码

}catch(异常对象){

	//捕捉到异常之后执行的代码

}

check异常:

IOException(文件异常)

ParseException(编译时异常)

InterruptedException( 线程执行的时候被中断)

SQLException(数据库异常)

非check异常:

Throwable(Java语言中所有错误或异常的父类)

|

|-- Exception(异常)

| |

| |-- 运行时异常(非检查异常),RuntimeException

| | |

| | |-- ArithmeticException(算术异常)

| | |-- NumberFormatException(数字格式异常)

| | |-- NullPointerException(空指针异常)

| | |-- StringIndexOutOfBoundsException(字符串索引越界异常)

| | |-- ArrayIndexOutOfBoundsException(数组索引越界异常)

| | |-- IndexOutOfBoundsException(索引越界异常)

| | |-- ClassCastException(类型转换异常)

| |

| |-- 非运行时异常(编译异常,检查异常),Exception

|

|-- Error(错误)

Exception:程序中出现的异常

Error:一般指虚拟机出现的错误

运行时异常:编写程序和编译程序时不会出现异常,但是运行的时候有可能出现异常

非运行时异常:在编写程序或编译程序时就出现了异常,需要异常处理

catch:可以有多个,但是范围必须由小到大

抛异常:

1.在方法定义时,指定能够抛出哪些异常的类型

2.抛出异常:throw new 异常对象()

自定义异常:可以继承RuntimeException,调用一个父类的有参构造器传递信息

	public static void getDate(String s) throws ParseException {
		SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
//		Date date = null;
//		try {
//			 date = fmt.parse(s);
//		} catch (ParseException e) {
//			// e.printStackTrace();
//			System.out.println("出现了日期转换异常");
//		}
		Date date = fmt.parse(s);
		System.out.println(date);
	}
	
	/*
	 * 	重写中:子类重写方法的异常对象要小于等于父类的异常对象
	 * 	父类的方法没有异常,子类重写的方法也不能有异常对象
	 */
	/*
	 * 	抛异常
	 *	1.在方法定义时,指定能够抛出哪些异常的类型
	 *	2.抛出异常:throw new 异常对象()
	 */
	public static void setAge(int age) throws RuntimeException {
		if(age<0) {
			throw new AgeException("年龄错误");
		}
		System.out.println("年龄:"+age);
	}

	public static void main(String[] args) {
		try {
			getDate("2021-01");
		} catch (ParseException e) {
			// e.printStackTrace();
			System.out.println("出现了日期转换异常");
		}
		System.out.println("ok");
		
		try {
			setAge(-60);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		setAge(60);
	}
// 自定义异常
public class AgeException extends RuntimeException {
	
	public AgeException(String message) {
		super(message);
	}

}

try:将有可能发生异常的代码放在try里

catch:通过大于等于本身异常进行捕获

finally:无论是否有异常,都会执行(System.exit(0):退出程序除外)

try可以分别和catch,finally连用,也可以三个一起使用

try,catch里有return,finally也会执行,且在return之前执行

public static int method() {
		int[] arr = { 1, 2, 3, 4, 5 };
		int j = 9;
		for (int i = 0; i <= arr.length; i++) {
			try {
				System.out.println("当前元素:" + arr[i]);
				j++;//10
				return j;//10
			} catch (RuntimeException e) {
				System.out.println("数组下标越界异常");
			} finally {
				System.out.println("当前下标是:" + i);
				j++;//11
				return j;
			}
		}
		return j;
	}
	
	public static int show() {
		int a = 1;
		try {
			return a++;
		}catch(Exception e) {
			return a++;
		}finally {
			return a++;
		}
	}

	public static void main(String[] args) {
		/*
		 * 	当前元素:1
		 * 	当前下标:0
		 * 	11
		 */
		System.out.println(Test03.method());
		System.out.println(show());//2
//		try {
//			int a = 0 / 0;
//		} catch (Exception e) {
//			System.out.println("出现了异常");
//			System.exit(0);
//		} finally {
//			// 无论是否有异常,都会执行(System.exit(0);//退出程序除外)
//			System.out.println("finally里的代码");
//		}
		
//		try {
//			int a = 0/0;
//		}finally {
//			System.out.println("finally里的代码");
//		}
//		System.out.println("ok");
	}

final,finally,finalize的区别

1.final修饰类不能被继承,修饰方法不能被重写,修饰变量值不能改变

2.finally,在异常处理中,一定能执行的部分(除了System.exit(0))

3.finalize,Object中的方法,在销毁对象之前调用,不建议重写

Java.lang.RuntimeException与java.lang.Exception区别

RuntimeException:这个类出现的异常可以不处理即如果某个异常类型为RuntimeException的子类的话就可以不 用try catch来处理。但Exception这个类的异常就必须使用try catch 来处理异常

File

File在io包中

IO:Input Output,输入输出

文件路径,推荐使用相对路径,不要使用绝对路径(完整的路径,比如d:\a.txt)使用绝对路径不能跨平台

相对路径,是从项目路径开始

判断文件是否存在:file.exists()

创建文件:file.createNewFile()

文件长度:file.length()

文件路径(相对路径):file.getPath()

路径分隔符:/(Unix、Linux的分隔符,Windows也识别)

不要使用\(只有DOs和Windows识别)

获取当前操作系统的分隔符:File.separator

文件路径(绝对路径):file.getAbsolutePath()

设置最后修改时间:setLastModified();

获取最后修改时间:lastModified()

只获取文件名(不包含路径):getName()

获取父级名称:getParent()

设置只读:setReadOnly()

设置是否可写:setWritable()

是否是隐藏文件:isHidden

判断是否是文件:isFile()

判断是否是文件夹(目录):isDirectory()

创建文件夹:mkdirs()

删除文件夹:delete()

获取到文件夹下面的所有文件:file.listFiles()

	File[] files = file.listFiles();
		for (File f : files) {
			if(f.isFile()) {
				System.out.print("文件:");
			}else {
				System.out.print("目录:");
			}
			System.out.println(f.getName());
		}
	}

IO流

IO流

|

|-- 字节流(适合操作二进制数据)

| |

| |-- InputStream(输入流)

| | |

| | |-- FileInputStream(文件输入流)

| | | |

| | | |-- BufferedInputStream(缓冲输入流)

| | | |-- DataInputStream(数据输入流)

| | |-- ObjectInputStream(对象输入流)

| | |-- ... ...

| |

| |-- OutputStream(输出流)

| |

| |-- FileOutputStream(文件输出流)

| |-- FilterOutputStream(过滤输出流)

| | |-- BufferedOutputStream(缓冲输入流)

| | |-- DataOutputStream(数据输出流)

| | |-- PrintStream(打印流)

| |-- ObjectOutputStream(对象输出流)

| |-- ... ...

|

|-- 字符流(适合操作文本数据)

|

|-- Reader(读取流)

| |

| |-- InputStreamReader(输入流读取器)

| | |-- FileReader(文件读取器)

| |-- BufferedReader(缓冲读取器)

| |-- ... ...

|

|-- Writer(写入流)

|

|-- OutputStreamWriter(输出流写入器)

| |-- FileWriter(文件写入器)

|-- BufferedWriter(缓冲写入器)

|-- PrintWriter(打印写入器)

|-- ... ...

 

FileOutputStream:文件输出流,向文件中写入数据

fos.write():向文件中写入数据

字符串.getBytes(编码):将字符串转换成指定编码格式的字节数组

FileOutputStream构造器参数:

文件名,是否追加(默认不追加)

参数2为是否追加,若是true则是追加

	public static void main(String[] args) throws IOException {
		/*
		 * FileOutputStream:文件输出流,向文件中写入数据 
		 * FileOutputStream 参数2为是否追加,为true时是追加
		 */
		FileOutputStream fos = new FileOutputStream("f1.txt", true);
		fos.write(97);
		byte[] bs = {65,66,67,68};
		fos.write(bs);
		fos.write(bs, 1, 3);
    	// 换行
		fos.write('\n');
		// 字符串.getBytes(编码):将字符串转成指定编码格式的字节数组
		fos.write("Hello World!".getBytes("UTF-8"));
		fos.close();
	}

FileInputStream:文件输入流,从文件中读取数据

fis.read(): 从此输入流中读取一个数据字节

	public static void main(String[] args) throws IOException {
		/*
		 * 	文件输入流:FileInputStream:将硬盘中的数据读取到内存中
		 */
		FileInputStream fis = new FileInputStream("f1.txt");
//		int len = fis.read();
//		System.out.println(len); // 97 a
//		
//		len = fis.read();
//		System.out.println(len);// 98 b
//		
//		len = fis.read();
//		System.out.println(len); // 99 c
//		
//		len = fis.read();
//		System.out.println(len); // -1
		
		int len;
		while((len = fis.read()) != -1) {
			System.out.print((char)len);
		}
		fis.close();
	}

 

将byte数组转字符串,new String(byte数组, 开始位置, 长度)

	public static void main(String[] args) throws IOException {
		FileInputStream fis = new FileInputStream("f1.txt");
//		byte[] b1 = new byte[2];
//		int len = fis.read(b1);
//		System.out.println(len); //2
//		System.out.println(new String(b1));
//		
//		byte[] b2 = new byte[2];
//		len = fis.read(b2);
//		System.out.println(len);
//		System.out.println(new String(b2));
//		
//		byte[] b3 = new byte[2];
//		len = fis.read(b3);
//		System.out.println(len);
//		System.out.println(new String(b3));

		byte[] bs = new byte[1024 * 10];// 每次最多能够读取的长度
		int len;// 真实长度
		String str = "";
		// len=fis.read(bs):将数据读取到byte数组中
		while ((len = fis.read(bs)) != -1) {
			// 将byte数组转字符串,new String(byte数组,开始位置,长度)
			str += new String(bs, 0, len);
		}
		fis.close();
		System.out.println(str);
	}

拷贝

	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner(System.in);
		System.out.println("输入源文件:");
		String str = sc.next();
		System.out.println("请输入目标文件:");
		String str2 = sc.next();
		
		FileInputStream fis = new FileInputStream(str);
		FileOutputStream fos = new FileOutputStream(str2);
		byte[] bs = new byte[10240];
		int len;
		while((len=fis.read(bs)) != -1) {
			fos.write(bs);
		}
		fis.close();
		fos.close();
		
		File file = new File(str);
		File file2 = new File(str2);
		file2.setLastModified(file.lastModified());
		
		System.out.println("拷贝成功!!");
	}

BufferedOutputStream,BufferedInputStream:缓冲流

低级流,节点流:直接操作硬件设备的流,比如FileOutputStream

高级流,处理流:不直接操作硬件设备,需要传入一个流来进行操作,比如BufferedOutputStream

	public static void main(String[] args) throws IOException {
		// write();

		BufferedInputStream bis = new BufferedInputStream(new FileInputStream("f2.txt"));
		byte[] bs = new byte[10240];
		int len;
		String str = "";
		while ((len = bis.read(bs)) != -1) {
			str += new String(bs, 0, len);
		}
		bis.close();
		System.out.println(str);
	}
	// Ctrl+1
	private static void write() throws FileNotFoundException, IOException {
		// 缓冲流
		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("f2.txt"));
		byte[] bs = { 97, 98, 99, 100 };
		bos.write(bs, 0, 2);
		bos.write('\n');
		bos.write("hello".getBytes());
		bos.close();
	}

DateOutputStream,DataInputStream:数据流,高级流

public class DataStream {

	public static void main(String[] args) throws IOException {
		write();
		// 数据流 高级流
		DataInputStream dis = new DataInputStream(new FileInputStream("f3.txt"));
		System.out.println(dis.readInt());
		System.out.println(dis.readUTF());
		System.out.println(dis.readDouble());
		dis.close();
		
	}

	private static void write() throws FileNotFoundException, IOException {
		DataOutputStream dos = new DataOutputStream(new FileOutputStream("f3.txt"));
		dos.writeInt(100);
		dos.writeUTF("Hello World!");
		dos.writeDouble(3.14);
		dos.close();
	}

}

ObjectOutputStream,ObjectInputStream:对象流,高级流

ObjectOutputStream:将对象转成byte数组

ObjectInputStream:将byte数组转成对象

序列化:将对象转成byte数组、字符串等。

反序列化:将byte数组、字符串等转成对象。

// 若想进行二进制序列化,实现Serializable(可序列化接口)
public class Emp implements Serializable{
​
    private String name;
    private double salary;
​
    public String getName() {
        return name;
    }
​
    public void setName(String name) {
        this.name = name;
    }
​
    public double getSalary() {
        return salary;
    }
​
    public void setSalary(double salary) {
        this.salary = salary;
    }
​
    @Override
    public String toString() {
        return "Emp [name=" + name + ", salary=" + salary + "]";
    }
​
}
public class ObjectStream {
​
    public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
        // write();
        
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("emp.txt"));
        // 数据写入到对象中(反序列化的过程)
        Emp emp = (Emp) ois.readObject();
        ois.close();
        System.out.println(emp);
    }
​
    private static void write() throws IOException, FileNotFoundException {
        // 对象流,高级流
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("emp.txt"));
        Emp emp = new Emp();
        emp.setName("tom");
        emp.setSalary(18000);
        // 对象写入到流中(序列化的过程)
        oos.writeObject(emp);
        oos.close();
    }
​
}
​

PrintStream:打印流

	public static void main(String[] args) throws FileNotFoundException {
		//打印流
//		PrintStream ps = new PrintStream("p.txt");
//		ps.println("Hello Java");
//		ps.print("hell");
//		ps.close();
		
		//System.out.println();
		PrintStream ps = new PrintStream(System.out);
		ps.println("hello");
	}

字符流

FileWriter FileReader,文件读写,低级流(节点流)

	public static void main(String[] args) throws IOException {
		FileWriter fw = new FileWriter("w1.txt");
		fw.write(97);
		char[] cs = { '你', '好', '你', '是', '小', '丑' };
		fw.write(cs);
		fw.write(cs, 0, 2);// 写入的开始位置和写入的长度
		fw.write("helloworld", 2, 3);
		fw.write("高斯林\n");
		fw.write("埃里森");
		fw.close();

		FileReader reader = new FileReader("w1.txt");
		char[] c = new char[10240];
		int len;
		String str = "";
		while ((len = reader.read(c)) != -1) {
			str += new String(c, 0, len);
		}
		reader.close();
		System.out.println(str);

	}

BufferedWriter,BufferedReader,缓冲读写流,高级流

PrintWriter,打印写入器

	public static void main(String[] args) throws FileNotFoundException {
		PrintWriter out = new PrintWriter("p.txt");
		out.println(100);
		out.println("Hello World");
		out.close();
		
		Scanner sc = new Scanner(new File("p.txt"));
		System.out.println(Integer.parseInt(sc.nextLine()));
		//sc.nextLine();
		System.out.println(sc.nextLine());
	}

 

多线程

并发:指两个或多个事件在同一个时间段内发生

并行:指两个或多个时间在同一时刻发生(同时发生)

 

进程:

线程:线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少

有一个线程。一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程

程序。 简而言之:一个程序运行后至少有一个进程,一个进程中可以包含多个线程。

 

线程调度:

分时调度: 所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU 的时间。

抢占式调度: 优先让优先级高的线程使用 CPU,如果线程的优先级相同,

那么会随机选择一个(线程随机性),Java使用的为 抢占式调度。

主线程:执行主(main)方法的线程

单线程程序:java程序中只有一个线程

 

创建多线程程序的方式一:

java.lang.Thread类:是描述线程的类

实现步骤:

1.创建一个Thread类的子类(继承Thread类)

2.重写run方法,设置线程的任务

3.创建Thread类的子类对象

4.调用Thread类中的start方法,开启新的线程,执行run方法

// 1. 创建一个Thread类的子类
public class MyThread extends Thread {
	// 2.在Thread类的子类中重写Thread类中的run方法,设置线程任务

	@Override
	public void run() {
		for (int i = 0; i < 20; i++) {
			System.out.println("run:" + i);
		}
	}
}
	public static void main(String[] args) {
		
		// 3. 创建Thread类的子类对象
		MyThread mt = new MyThread();
		// 4.调用Thread类中的start方法,开启新的线程,执行run方法
        // start的方法一个线程只能调用一次
		mt.start();
		
		for (int i = 0; i < 20; i++) {
			System.out.println("main:" + i);
		}
	}

获取线程名称:

  • 1.使用Thread类中的方法getName()

    String getName():返回该线程的名称

  • 2.可以先获取到当前正在执行的线程,使用线程中的方法getName()获取线程的名称

    static Thread currentThread()返回当前正在执行的线程对象的引用

public class MyThread_getName extends Thread{

	@Override
	public void run() {
 
	}
}
	public static void main(String[] args) {
		MyThread_getName mt = new MyThread_getName();
		mt.start();// Thread-0
		
		new MyThread_getName().start();// Thread-1
		new MyThread_getName().start();// Thread-2
		// 获取主线程名称 main
		System.out.println(Thread.currentThread().getName());
	}

设置线程名称:

public class Thread01 {

	public static void main(String[] args) {
		MyThread_getName mt = new MyThread_getName();
		mt.start();// Thread-0
		
		new MyThread_getName().start();// Thread-1
		new MyThread_getName().start();// Thread-2
		// 获取主线程名称 main
		System.out.println(Thread.currentThread().getName());
	}

}
	public static void main(String[] args) {
//		MyThread_setName mt = new MyThread_setName();
//		// 设置线程名称
//		mt.setName("王昊");
//		mt.start();
		
		// 设置线程名称
		new MyThread_setName("旺财").start();
	}

sleep:让程序睡眠

public static void sleep(long millis)

式当前正在执行的线程以指定的毫秒数暂停,毫秒数结束后,线程继续执行

	public static void main(String[] args) {
		// 模拟秒表
		for (int i = 1; i <= 60; i++) {
			System.out.println(i);
			try {
				// Thread 类的sleep方法让程序睡眠1秒钟
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

创建多线程程序的方式二:

1.实现Runnable接口

2.重写run方法

3.创建一个Runnable接口的实现类对象

4.创建Thread对象,构造方法中传递Runnable接口的实现类对象

5.调用Thread类中的start方法,开启新的线程

// 1.创建一个Runnable接口的实现类
public class RunnableImpl implements Runnable {

	// 2. 在实现类中重写Runnable接口的run方法,设置线程任务
	@Override
	public void run() {
		for (int i = 0; i < 20; i++) {
			System.out.println(Thread.currentThread().getName() + "-->" + i);
		}
	}
}
	public static void main(String[] args) {
		// 3. 创建一个Runnable接口的实现类对象
		RunnableImpl run = new RunnableImpl();
		// 4. 创建Thread类对象,构造方法中传递Runnable接口的实现类对象
		Thread t = new Thread(run);
		// 5.调用Thread类中的start方法,开启新的线程
		t.start();
		
		for (int i = 0; i < 20; i++) {
			System.out.println(Thread.currentThread().getName() + "-->" + i);
		}
	}

第一种方式:使用简单,但是影响子类继承其他类

第二种方式:不影响继承,降低了程序的耦合度(解耦)

线程安全问题

 

解决线程安全问题:

方式一:使用同步代码块

格式:synchronized(锁对象){

可能会出现线程安全问题的代码(访问了共享数据的代码)

}

注意:

1. 通过代码块中的锁对象,可以使用任意的对象

2. 但是必须保证多个线性使用的锁对象是同一个

3. 把同步代码块锁住,只让一个线程在同步代码块中执行

public class TicketThread implements Runnable {

	private int ticket = 100;

	// 创建一个锁对象
	Object obj = new Object();

	// 卖票
	@Override
	public void run() {
		while (true) {
			synchronized (obj) {
				// 判断票是否存在
				if (ticket > 0) {
					// 票存在 ticket--
					System.out.println(Thread.currentThread().getName() + "=>正在卖第" + ticket + "张票");
					ticket--;
				}
			}
		}
	}
}
	public static void main(String[] args) {
		TicketThread t = new TicketThread();
		Thread t0 = new Thread(t);
		Thread t1 = new Thread(t);
		Thread t2 = new Thread(t);
		t0.start();
		t1.start();
		t2.start();
	}

方式二:使用同步方法

使用步骤:1.把访问了共享数据的代码抽取出来,放到一个方法中

2.在方法上添加synchronized修饰符

格式:

访问修饰符 synchronized 返回值类型 方法名(参数列表){

可能会出现线程安全问题的代码(访问了共享数据的代码)

}

public class TicketThread implements Runnable {

	// 定义一个多个线程共享的票源
	private int ticket = 100;

	@Override
	public void run() {
		while(true) {
			payTicket();
		}
	}

	public synchronized void payTicket() {
		if (ticket > 0) {
			System.out.println(Thread.currentThread().getName() + "=>正在卖第" + ticket + "张票");
			ticket--;
		}
	}
}
    public static void main(String[] args) {
        TicketThread t = new TicketThread();
        Thread t0 = new Thread(t);
        Thread t1 = new Thread(t);
        Thread t2 = new Thread(t);
        t0.start();
        t1.start();
        t2.start();
    }

同步:顺序执行(A,B,C,D 接力赛)

异步:同时执行(A,B,C,D 比赛)

死锁:多个线程访问共同资源,且处于互相等待的状态,会导致死锁

sleep让当前线程处于休眠状态,但是不释放资源

wait让当前线程处于等待状态,释放资源,但是需要通过notify/notifyAll进行唤醒

线程的五种状态(线程生命周期)

1.新建状态:线程被建立

2.就绪状态:将新建的线程,加入到执行队列中

3.运行状态:线程被执行

4.阻塞状态:执行过程中发生了等待状态,导致线程暂停

5.消亡状态:线程结束

23种设计模式

单例模式:只有一个实例

1.构造方法要私有化

2.设置一个公共的静态方法返回当前类对象

饿汉模式:事先创建好对象

懒汉模式:使用时才会创建

public class Earth {
    // 懒汉模式:使用时才会创建
//  private static Earth earth;
//  
//  private Earth() {
//      System.out.println("创建对象");
//  }
//  
//  public static Earth getEarth() {
//      if(earth == null) {
//          return earth = new Earth(); 
//      }
//      return earth;
//      
//  }
    // 饿汉模式:事先创建好对象
    private static Earth earth = new Earth();
​
    private Earth() {
        System.out.println("创建对象");
    }
​
    public static Earth getEarth() {
        return earth;
    }
​
}
    public static void main(String[] args) {
        Earth e1 = Earth.getEarth();
        Earth e2 = Earth.getEarth();
        System.out.println(e1 == e2);// true
    }

工厂模式:工厂里有n个管理类,同一由工厂来产生对象

枚举:将可以选择的数据,一一列出,只能选择给你列出来的数据

比如:在杨洋,邓论,李现,王嘉尔中输入你喜欢的男明星

补充:

面向对象之间的关系:

1.继承(泛化):类与类之间的关系就叫做继承。(Cat 继承 Animal)

2.实现:类与接口之间的关系。(Bird 实现 Fly接口)

3.依赖:一个必须用到另一个。(演奏者演奏乐器的前提得给一个乐器)

4.关联:一个里边有另一个。

聚合:关系不是特别强烈的,可有可无的是聚合。(Person中有一个属性是Card)

组合:关系比较强烈的,必须有的,叫做组合。(Person中有Body)

is a(继承,实现) use a(依赖) has a(关联)

JDK 8新特性

lamada表达式

主要针对是接口,且接口中只有一个抽象方法,替换匿名内部类

无参数无返回值

public class Demo01 {
​
    public static void main(String[] args) {
        Interface1 interface1 = new Interface1() {
​
            @Override
            public void method() {
                // TODO Auto-generated method stub
                System.out.println("哈哈哈哈哈");
            }
​
        };
        interface1.method();
        // 主要针对是接口,且接口中只有一个抽象方法,替换匿名内部类的
        // ①lamada表达式
        Interface1 interface2 = () -> {
            System.out.println("啦啦啦啦");
        };
        interface2.method();
        // ②由于只有一条语句,所以{}可省略
        Interface1 interface3 = () -> System.out.println("hello");
        interface3.method();
    }
​
}
​
interface Interface1 {
    // 无参数无返回值
    public abstract void method();
}
​

无参数有返回值

public class Demo02 {
​
    public static void main(String[] args) {
        // ①
        Interface2 i1 = new Interface2() {
​
            @Override
            public int method() {
                // TODO Auto-generated method stub
                return 100;
            }
        };
        System.out.println(i1.method());
​
        // ②
        Interface2 i2 = () -> {
            return 200;
        };
        System.out.println(i2.method());
​
        // ③
        Interface2 i3 = () -> 300;
        System.out.println(i3.method());
    }
​
}
​
interface Interface2 {
    // 无参数有返回值
    int method();
}
​

有参数无返回值

public class Demo03 {
​
    public static void main(String[] args) {
        // ①
        interface3 i1 = new interface3() {
​
            @Override
            public void method(int x, int y) {
                // TODO Auto-generated method stub
                System.out.println("x=" + x + ",y=" + y);
            }
        };
        i1.method(1, 2);
​
        // ②
        interface3 i2 = (int x, int y) -> {
            System.out.println("x=" + x + ",y=" + y);
        };
        i2.method(3, 4);
​
        // ③
        interface3 i3 = (int x, int y) -> System.out.println("x=" + x + ",y=" + y);
        i3.method(5, 6);
​
        // ④
        interface3 i4 = (x, y) -> {
            System.out.println("x=" + x + ",y=" + y);
        };
        i4.method(7, 8);
​
        // ⑤
        interface3 i5 = (x, y) -> System.out.println("x=" + x + ",y=" + y);
        i5.method(9, 10);
​
    }
​
}
​
interface interface3 {
    // 有参数无返回值
    public abstract void method(int x, int y);
}

有参数有返回值

public class Demo04 {
​
    public static void main(String[] args) {
        // ①
        interface4 i1 = new interface4() {
​
            @Override
            public int method(int x, int y) {
                // TODO Auto-generated method stub
                return x + y;
            }
        };
        System.out.println(i1.method(1, 2));
        // ②
        interface4 i2 = (int x, int y) -> {
            return x + y;
        };
        System.out.println(i2.method(3, 4));
​
        // ③
        interface4 i3 = (int x, int y) -> x + y;
        System.out.println(i3.method(5, 6));
​
        // ④
        interface4 i4 = (x, y) -> {
            return x + y;
        };
        System.out.println(i4.method(7, 8));
​
        // ⑤
        interface4 i5 = (x, y) -> x + y;
        System.out.println(i5.method(9, 10));
    }
​
}
​
interface interface4 {
    // 有参数有返回值
    public abstract int method(int x, int y);
}

集合遍历,排序

public class Demo05 {
​
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("tom");
        list.add("rose");
        list.add("jack");
        list.add("kimi");
        list.add("july");
​
        // 函数式接口 -- Consumer接口
        list.forEach(new Consumer<String>() {
            @Override
            public void accept(String t) {
                System.out.println(t);
            }
        });
        System.out.println("====================================");
        list.forEach((String t) -> System.out.println(t));
        System.out.println("====================================");
        list.forEach((t) -> System.out.println(t));
        System.out.println("====================================");
        list.forEach(t -> System.out.println(t));
​
        // 比较
//      Collections.sort(list,new Comparator<String>() {
//
//          @Override
//          public int compare(String o1, String o2) {
//              // TODO Auto-generated method stub
//              return o2.compareTo(o1);
//          }
//      });// 升序
        // Collections.sort(list, (o1, o2) -> o1.compareTo(o2));
        // 降序
        Collections.sort(list, (o1, o2) -> o2.compareTo(o1));
        System.out.println(list);
​
    }
​
}

可以调用静态方法

public class Demo06 {
​
    public static void main(String[] args) {
        Interface6 i1 = new Interface6() {
​
            @Override
            public int getInt(String s) {
                // TODO Auto-generated method stub
                return Integer.parseInt(s);
            }
        };
        System.out.println(i1.getInt("123") + 1);
​
        Interface6 i2 = (s) -> Integer.parseInt(s);
        System.out.println(i2.getInt("456") + 1);
​
        // 可以调用静态方法
        Interface6 i3 = Integer::parseInt;
        System.out.println(i3.getInt("789") + 1);
​
        System.out.println("=============================");
        ArrayList<String> list = new ArrayList<>();
        list.add("tom");
        list.add("rose");
        list.add("jack");
        list.add("kimi");
        list.add("july");
        list.forEach(System.out::println);
    }
​
}
​
interface Interface6 {
    int getInt(String s);
}
​

构造方法

public class Demo07 {
​
    public static void main(String[] args) {
        Interface7 i1 = new Interface7() {
​
            @Override
            public Person getPerson() {
                return new Person();
            }
        };
        i1.getPerson();
​
        // 构造方法
        Interface7 i2 = Person::new;
        i2.getPerson();
​
        // 有参构造方法
        Interface8 interface8 = Student::new;
        interface8.getStudent("tom", 18);
    }
​
}
​
class Person {
​
    public Person() {
        System.out.println("创建Person对象");
    }
​
}
​
interface Interface7 {
    public Person getPerson();
}
​
class Student {
    public Student(String name, int age) {
        System.out.println(name + "\t" + age);
    }
}
​
interface Interface8 {
    public Student getStudent(String name, int age);
}
​

时间类

LocalDate

LocalDate.now():获取当前系统时间

LocalDate.of(2045, 12, 12): 指定时间

通过控制当前赋值的正负数,完成是加还是减

plusYears(-3):年份

plusMonths(-13):月份

plusDays(1):日期

plusWeeks(2):周,1代表7天

        Calendar cal = Calendar.getInstance();
        System.out.println(cal.getTime());
        SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println(fmt.format(cal.getTime()));
        System.out.println(cal.get(Calendar.MONTH) + 1);// 0-11
        System.out.println(cal.get(Calendar.DAY_OF_WEEK) - 1);// 周日是第一天 1-7// jdk 8之后新增时间类
        LocalDate ld = LocalDate.now();// 获取当前系统时间
        System.out.println(ld);
        LocalDate ld2 = LocalDate.of(2045, 12, 12);// 指定时间
        System.out.println(ld2);
        // 通过控制当前赋值的正负数,完成是加还是减
        //  
        ld2 = ld2.plusYears(-3);
        System.out.println(ld2);
        // 月份
        ld2 = ld2.plusMonths(-13);
        System.out.println(ld2);
        // 日期
        ld2 = ld2.plusDays(1);
        System.out.println(ld2);
        // 周 1代表7天
        ld2 = ld2.plusWeeks(2);
        System.out.println(ld2);        
        // 格式化
        DateTimeFormatter dtf = DateTimeFormatter.ISO_LOCAL_DATE;// 获取系统设置好的时间格式
        System.out.println(dtf);
        System.out.println(dtf.format(ld));
        DateTimeFormatter dtf2 = DateTimeFormatter.ofPattern("yyyy/MM/dd");//自定义格式
        System.out.println(dtf2.format(ld));

LocalTime

// 时分秒毫秒
        LocalTime lt = LocalTime.now();
        System.out.println(lt);
        // 格式化
        DateTimeFormatter d1 = DateTimeFormatter.ofPattern("HH:mm:ss");// HH:24进制  hh:12进制
        System.out.println(d1.format(lt));

LocalDateTime

// 年月日时分秒毫秒
        LocalDateTime lt2 = LocalDateTime.now();
        System.out.println(lt2);// 2021-10-09T14:21:27.422
        DateTimeFormatter d2 = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss");
        System.out.println(d2.format(lt2));

 

快捷键:

万能键: alt+/(?),main=>主方法

复制:ctrl+c

粘贴: ctrl+v

剪切: ctrl+x

撤回:ctrl+z

删除一行:ctrl+d

保存: ctrl+s

单行注释:ctrl+/(?)

多行注释:ctrl+shift+/

变成大写:ctrl+shift+x

变成小写:ctrl+shift+y

posted @   晚街  阅读(76)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示