Java语法

类:类是一个模板,描述一类对象的行为和状态

对象:对象是类的一个实例,有状态和行为;比如说。一只狗,状态就是他有品种,名字,颜色等,行为

有摇尾巴,叫,吃等

方法:方法就是行为,一个类可以有很多方法,逻辑运算,数据



修改等都是在方法中完成的

实例变量:每个对象都有自己的实例变量,对象的状态就是由这些实例变量的值决定的



Java基本数据类型

变量是申请内存来储值,当创建变量的时候需要在内存中申请空间

根据变量的类型来为变量分配存储空间,只用来储存该类型数据

Java两大数据类型

内置数据类型和引用数据类型



内置数据类型

八种内置数据类型(六种数字数据类型,一种字符类型还有一种布尔类型)

不用记范围,直接打印输出  Inteager.size 这样就可以打印出范围



引用数据类型

引用数据类型类似于指针,引用类型指向一个对象,指向对象的变量就是引用变量。

这些变量在声明时被指定为一个特定的类型,一旦申明变量,类型就不能改变。

对象,数组都是引用数据类型

所有引用类型的默认值都是null


变量类型

类变量:独立与方法之外的变量,用ststic修饰

实例变量:独立与方法之外的变量,不用ststic修饰

局部变量:类的方法中的变量



Java 局部变量

局部变量声明在方法、构造方法或者语句块中;

局部变量在方法、构造方法、或者语句块被执行的时候创建,当它们执行完成后,变量将会被销毁;

访问修饰符不能用于局部变量;

局部变量只在声明它的方法、构造方法或者语句块中可见;

局部变量是在栈上分配的。

局部变量没有默认值,所以局部变量被声明后,必须经过初始化,才可以使用。



java修饰符



Java方法

方法定义的格式:

修饰符 返回值类型 方法名称 (参数类型  参数名称){

方法体

return  返回值;

}

解释:

修饰符:目前有固定写法。两个关键字 public static

返回值类型:方法最终的数据是什么类型

方法名称:自定义的名字,首字母小写,从第二个单词开始每个单词首字母大写

参数类型:进入方法的数据是什么类型

参数名称:进入方法的数据,对应的名称

方法体:需要执行的若干行代码

return :第一个作用一旦执行结束当前方法,第二带着后面的返回值交给调用处

返回值:方法的最终数据

注意事项:

返回值类型必须和返回值对应

如果参数多个,那么使用都用逗号分隔

如果不需要参数,那么小括号可以留空

定义一个没有返回值的方法

修饰符 void 方法名称 (参数类型 参数名称){

方法体

return ;//最后一行的return一般都是省略不写

}

注意事项

1.返回值没有不代表没有参数,参数和返回值没有必然联系

2.不能return一个具体的返回值

viod没有返回值

3.如果最后一行是“return”,那么可以不写,写与不写完全等效

4.没有返回值的方法,只能使用单独调用,不能使用打印调用或者赋值调用【重要】







返回值

只能有一个或者没有




demo 遍历数组

1.将数组中的元素逐一打印出来

2’定义一个数组

*返回值类型:只是打印显示而已,没有结果数据,所以用void

*方法名称:printArray

*参数列表:需要给我一个数组,我才能遍历它,所以需要一个int【】数组

3.调用方法:传入一个数组



有无返回值的对比

对比两种情况:

1.定义一个方法,用来【求出】数组元素的总和(告诉我最终的结果)

2.定义一个方法,用来【打印】数组元素的总和(自己打印就得了,不用告诉我结果)

结论:

需要计算的有返回值

只需要打印的就没有返回值



方法的重载(Overload )

方法重载:方法的名称相同,但是参数列表不同(Overload)

达到效果:对于类似功能的多个方法,只要记住一个相同的名字即可,可以根据参数列表的不同自动适配

注意事项:

1.参数个数不同

2.参数类型不同

3.参数的多类型的顺序不同(表达式当中需要运算的数据类型不一样,怎么办?谁的数据范围大,结果就是谁):比如先int后double,先double后int

重载与下列因素无关:

1.与返回值类型无关,无法根据返回值的不同进行重载;

2.与参数的名称无关,比如int a,int b和int x,int y;



参数传递

参数传递:在调用方法的时候,向方法内传入一些数据的动作

【形式参数】:在“定义”方法的时候,写在小括号之内的参数

例如:public static  int sum(int a,int b){...}这里的a和b是在定义的时候写的,所以就是形式参数

【实际参数】;在“调用”方法的时候,真正传入方法里的数据,叫做实际参数

例如:int num=sum(10,20),这里的10和20是在调用方法的时候传入方法的,所以他们是实际参数


参数传递的过程中,有两项规则

1.对于基本数据类型(以及String)来说,形式参数的操作不会影响实际参数

2.对于引用数据类型(除了String)来说,形式参数的操作会影响到实际参数



类的定义

类是用来模仿现实事物的代码手段,事物分为属性,行为两个部分,类中也对应的包含了两个部分

1.成员变量(属性):将变量位置直接定义在类中,在方法外即为成员变量

2.成员方法(行为):将普通的方法去掉stataic关键字,即为成员方法



两个对象内存图

一个对象


对比局部变量和成员变量的不同

1.定义的位置不同【重点记忆】

局部变量:定义在方法内部

成员变量:直接定义在类中,在方法外面的


2.内存中的位置不一样

局部变量:在栈内存中,stack

成员变量:在堆内存中,heap


3.生命周期不一样

局部变量:随着方法的进栈而出现,随着方法的出栈而消失

成员变量:随着对象被创建而出现,随着对象被JVM回收而消失


4.默认值不一样【重点记忆】

局部变量:没有默认值,必须赋值之后才能使用

成员变量:如果没有赋值,那么会有一个默认值



private关键字

一旦使用了private关键字对成员进行了修饰,那么超出了本类范围之外,就不能访问了

如果需要使用private修饰的成员变量,可以使用“间接访问”

为private成员变量编写一对儿Setter Getter方法

例如:

在最前方加上一个private 

专门定义了一个成员方法用来设置成员变量的数据,Setter方法

public void setAge (int num){

     age = num;

}

专门定义了一个方法用来获取成员变量的数据,Getter方法

public void getAge(){

return age;

}



this关键字

当局部变量与和成员变量重名的时候,方法中会根据“就近原则”使用局部变量

如果希望区分一下

this.成员变量名


this关键字的静电作用:将重名的成员变量和局部变量区分开


扩展:

this关键字其实代表的是“当前对象”:通过谁调用了方法,谁就是this



构造方法:

专门用来创建对象的方法,当通过new关键字创建对象时,其实就是在调用构造方法

格式:

public 构造方法名 (参数类型 参数名称){

方法体

return  //通常最后一行return省略不写

注意:

1.构造方法不能写放回值类型,连void都不能写

2.构造方法的名称必须和所在的类名完全一样,连大小写也要一样

}

3.构造方法的调用格式就是创建对象的格式 


构造方法重载的好处:

定义一个无参数的构造方法,可以直接new对象

定义一个重载的全参数的构造方法,可以在new对象的同时方便对成员变量进行赋值

注意事项:

1.构造方法根本不写返回值类型,连void都不写

2.构造方法的名称和所在类名称必须完全相同,连大小写都要一样

3.构造方法也是可以进行承载的

4.构造方法如果没有自定义,那么将会默认赠送一个,如果自定义了至少一个,那么就不再赠送默认的


如何定义一个标准的类:

1.所有的成员变量都需要使用private关键字私有化

2.为每一个成员变量编写一对Getter Setter 方法

3.编写一个无参数的构造方法

4.编写一个全参数的构造方法



布尔类型的boolean值,那么setXxx规则不变,而getXxx余姚写成isXxx的形式

private boolean male;

public void setMale(boolean male){

    this.male = male;

}

public boolean isMale (){

return male;

}



字符串的两个问题

1.对象肯定有一个类与之对应,那么字符串对应的类是谁,String

为什么String这个类,不需要导包就可以直接用?


所有的类都需要导包才能使用,除了两种情况

a. 要使用的目标类,和当前类位于同一个包下

b.要使用的目标类,位于java.lang包下,但是不包含子包内容


2.既然字符串是对象,那么为什么直接打印出来就是内容呢?

打印println方法 逻辑:

1.如果是字符串类型,那么就直接显示内容

2. 如果不是字符串类型,那么就想办法内部转换成字符串,然后再显示

一般的对象都是使用“类型信息+@+地址值”作为字符串内容的



字符串池

字符串是最为常用的对象,所以在程序设计中往往会出现很多个重复的字符串

为了节省内存,所以引入了“字符串池”的设计,可以重复利用字符串


关于字符串池的几点描述

1.字符串池是位于堆内存中的一小块空间,用来保存若干个字符串的地址值

2.字符串池当中绝对不会重复的字符串对应的地址,保证字符串不重复

3.凡是直接双引号的字符串默认都在池中,而new出来的字符串默认不在池中


对于基本类型来说,==是进行数据内容的相同比较,但是对于引用类型来说,==是进行地址值的相同比较

如果是两个对象,那么地址值必然不同,如果地址值相同,那么必然是同一个对象




字符串的内容不可变

字符串对象在内存中一旦被创建,那么内容不可以改变

字符串的内容不会发生改变,每当你觉得昊想是变了的时候,一定是创建了新的字符串



字符串的比较方法

如果使用 == 进行比较,那么是进行地址值的相同判断

如果希望进行字符串的内容比较,则需要使用String当中的成员方法


public  boolean equals (object obj); 进行字符串的内容比较,严格区分大小写。参数obj就是另一个对象(跟谁比 )。object也是一种类型,可以接受任何类型的数据

public boolean equalsIgnoreCase(String str);进行字符串的内容比较,但是忽略大小写 


注意事项:

1.要想进行字符串的内容比较,一定要使用equals方法,你要使用==运算

2.equals方法具有对称性,a.equals(b)和b.equals(a)效果一样

3. 小技巧,如果equals方法需要比较的两个字符串当中,有一个是常量,那么尽量将常量写在前面

4.直接写上的双引号就是字符串对象,所以用双引号直接点儿也能调用方法。



字符串的替换方法(敏感词过滤)

如果希望将字符串当中指定的部分进行替换操作,需要使用


public String replace (CharSequence olderStr,CharSequence newStr);将字符串当中所有出现的older部分,替换成为newOlder部分

参数olderStr代表需要替换的老字符串部分

参数newStr代表需要替换成为的新字符串部分

参数类型CharSequence现阶段可以简单地认为就是字符串String



字符串切割方法

使用方法

public String[] split(String regex);将regex作为标记进行切刀,返回切分之后的若干段字符串(字符串数组)

注意事项:

现阶段强烈推荐不要使用英文句点作为分割的标记

因为英文句点在正则表达式中有特殊含义

如果一定要使用英文句点,切割的标记应该使用“//.”(现阶段的固定写法)

而参数regex其实就是一个正则表达式  



集合

集合和已经学过的数组比较类似,本身也是一种引用类型。也可以存放很多个数据

区别在于数组的长度不可以改变,集合的长度可以任意改变

集合包含很多种,ArrayList,HashSet,LinkedList,HashMap......

现阶段我们只学习最为简单的ArrayList一种即可,其他的集合类似


使用:

java.util.ArrayList是一个类,使用三步,导包,创建,使用  

1.导包

import java.util.ArrayList

2.创建 

类名称 对象名 = new 类名称();

ArrayList<泛型> Array = new ArrayList<>();

泛型,也就是集合当中存放的都是同意类型的数据

注意:泛型只能是引用类型,不能是基本类型


3.使用 :



如何在集合中存储基本数据类型

基本类型       对应的包装类

byte                  Byte

short                 Short

int                    Integer     【特殊】

long                  Long

float                  Float

double             Double

char                Character    【特殊】

boolean           Boolean

从jdk1.5开始,基本数据类型可以和对应的包装类进行自动装箱拆箱

装箱:基本类型-->包装类

拆箱:包装类 -->基本类型



如何在集合中储存自定义数据类型



io流:

I:input,输入

o:output,输出

流:数据流



FileWriter 写文件

1.导包:

import java.io.FileWhiter;

2.创建,构造方法

public FileWriter(String fileName); 参数字符就是文件的路径名称

FileWriter fw = new FileWrite(“file01.txt”);

文件扩展名只能决定默认用什么软件打开软件,不能决定其内容


3.使用:成员方法

写数据:public void write (String str);参数就是需要写到文件中的字符串

关闭流:public void close();关闭释放相关资源


总结:

FileWriter基本使用步骤:创,写,关

注意事项:

1.千万不要忘记最后调用close方法进行关闭

2.创建的时候,如果提示可能有异常,那么就点击add throws...即可



FileWriter写数据的覆盖与追加

在使用FileWriter的时候:

1.如果指定的文件不存在,那么会自动创建该文件

2.如果指定的文件已经存在,那么将会覆盖写入

3.如果必须希望进行覆盖写入,而是希望追加,那么要用另外一种重载形式的构造方法

public FileWriter (String fileName , boolean append);第二个参数为true值,那么将会追加写入



文本文字就是数字

计算机当中一切都是数字,文本文件当中保存的就是数字

能够看到文字图形,是因为软件帮我们进行了翻译,翻译的规则就是:

ASCii码表,还有另外一张更大的表叫做Unicode码表

后者包含了全世界所有数以万计的文字


FileWriter提供了一种重载形式的write方法,可以直接根据数字写文件

public void write(int ch);参数就是单个文字所对应的数字值



FileWriter的重载形式



FileReader读数据的一般步骤

用来将文本文件中的字符读取到程序当中

1.导包

import java.io.FileReader;

2.创建

public FileReader(String fileName);参数任然是文件的路径名

FileReader fr = new FileReader("fileXxx.txt");

如果指定的文件名不存在,那么会直接报错 

3.使用

读取单个字符:public int read();读取下一个字符,得到对应的ASCII或者Unicode值

关闭流,释放资源:public void close;

三个步骤:创,读,关;



如何使用FileReader读取字符数组

为了提高效率。FileReafer提供了另外一种重载形式的read方法


public int read(char[] buf);

参数是一个字符数组,用来承载读取到的多个字符

返回值代表的是数组中读取到的有效个数



BufferWriter的缓冲原理

BufferWriter和FileWriter差不多,也是一种用来写文件的类,属于字符输出类

区别与BufferWriter肚子里有一个长度为8192的char[]性字符数组,当作缓冲区使用

每次在写数据时,实际上都是在不断地向缓冲数组中添加字符

如果缓冲数组已经满了,那么将会统一的写入到硬盘中去

如果还未写满,那么就等待下一次的写入

如果最终关闭流的时候,数组任未满,那么也会将剩余的有效部分写到硬盘文件里



如何使用BufferedWriter?

1.首先创建一个普通的BufferedWriter

2.将这个普通的FileWriter包装成为缓冲的BufferedWriter,用构造方法

3.后面的BufferedWriter使用的方法和FileWriter基本一致

构造方法

public Buffered(FileWriter fw);参数就是一个普通的FileWriter对象



BufferedReader的缓冲原理




接口

接口的好处:通用性,隔离性

 通用性:无论是医生还是警察还是司机

通用全都当作的学生对待

隔离性:无论是医生还是警察还是司机

特有的功能与我无关,我只关心学生相关的功能



接口的格式和组成部分

格式:

public interface 接口名称{

  //

}

接口中的组成成分

1.抽象方法[学习重点]

2.常量

3.默认方法(java8)

4.静态方法(java8)

5.私有方法(java9)



接口中抽象方法定义

格式:

public abstract 返回值类型 方法名称(参数类型 参数名称);

注意:

1.接口中的抽象方法,修饰如果写必须是public abstract

2.接口中的抽象方法,修饰符可以省略不写。默认就是public abstract

3.抽象方法只有方法头,没有方法体大括号



接口实现类的定义

如果想要使用定义好的接口,必须有一个接口的实现类

定义实现类格式为:

public class 实现类的名称 implements  接口名称 {

     //一定要覆盖写所有的抽象方法

}

注意:

什 么是覆盖重写Override 抽象方法

1.也就是将接口当中的抽象方法抄写过来

2.去掉abstract关键字

3.写上大括号方法体 


package day09demo01;

public class Catimplements Animal{

public  void eat (){

System.out.println("猫吃鱼");

};//吃东西

    public void sleep (){

System.out.println("猫睡觉");

};//睡觉

}


Cat就是Animal接口的实现类,Cat类实现了Animal接口。



接口与实现类的基本使用

创建:

接口名称 引用名 = new 实现类名称();

调用:

引用名.抽象方法名(参数);    

注意:

1.左面是接口类型,那么只能调用接口中定义好的内容,无法调用左侧实现类专有的方法

2.当调用接口当中的抽象方法时,真正进行运行的是右侧new的时候类的具体实现方法内容

3.总结记住一句话:调用的时候看左边,运行的时候看右边



面向接口编程

使用接口作为左侧类型的好处所在

屏蔽掉了右侧的个性特有的内容,达到隔离,统一的目的。


面向接口编程:

如果使用的功能,接口已经可以满足,那么就不在乎具体的类是谁,只在乎接口即可



Lambda表达式:(a,b)-> a + b

method方法需要一个Calaulator接口类型的参数

Lambda表达式就是充当了Calculator接口类型的参数

初步理解:

1.Lambda表达式前面的小括号,其实就是接口抽象方法的小括号

2.箭头代表拿着小括号的数据做什么事情,是一个指向的动作

3.箭头后面就代表这拿到了参数之后做什么事


Lambda表达式的语义本身就是代表了怎么做这件事情,没有对象概念在里面。



函数式接口

Java中使用Lambda表达式的前提是,必须有“函数式接口”

概念:有且仅有一个抽象方法的接口,叫做函数式接口 


如何才能万无一失地检测一下当前的接口是不是函数式接口呢?

用一个固定的格式写在public interface前一行即可

@FunctionalInterface

public interface 函数式接口名 {

  //  ...

}



Lambda的标准格式

Lambda表达式要想使用,一定要有函数式接口的推断环境

1.要么通过方法的参数类型来确定是哪个函数式接口

要么通过赋值操作来确定哪个是函数式接口


Lambda的格式就是为了将抽象方法,翻译成一下三点

1.一些参数(方法参数)

2.一个箭头

3.一些代码(方法体)


例如抽象方法

public abstract int sum(int a,int b);


翻译成为Lambda的标准格式

(int a,int b) -> {return a + b; }



Lambda表达式上下文推断

调用方法的时候,参数类型是函数式接口,所以Lambda可以推断出来是哪个接口

也可以根据赋值语句左侧的类型来进行Lambda上下文推断



Lambda的简便格式

1.在Lambda表达式当中凡是可以推导的,都是可以省略的 

2.如果参数有且仅有一个,那么小括号可以省略

3.如果语句只有一个,那么大括号和return也可以省略



前面学习的代码实现案例分析


1.创建一个集合用来存储5个英雄

创建一个Hero类,代表英雄

把集合内的对象换成hero对象

2.读文件,吧数据加到集合当中

3.判断一下集合中有没有内容,是不是新的


如果是新的队伍,没有人,就需要创建五个对象加入到集合中

如果不是新的队伍,已经有人了,就不需要创建了

遍历集合,输出其中的每一个对象的具体信息//循环5次进行遍历//统计一下综合战斗力是多少

判断一下集合是不是新的

if (isNew){

System.out.println("将集合重的数写到文件中”);

}

//如果不是新的,就什么也不用做

System.out.println("退出游戏")



方法引用(java 8)

Stream流(java 8)

模块化(java 9)



定义方法时,

有static的方法叫做静态方法

没有static的方法,叫做成员方法(实例方法)


定义静态方法的格式:

public static 返回值类型 方法名称(参数类型 参数名称){

   //方法体

}


定义成员方法的格式:

public 返回值类型 方法名称(参数类型 参数名称){

   //方法体

}


调用静态方法的格式

方法名(参数值);//直接调用本类中的静态方法,本类中的静态方法,也可以通过类名称调用

类名称.方法名(参数值);//调用另外一个类中的静态方法

调用成员方法的格式:

     类名称  对象名  =  new 类名称(); //首先创建对象

     对象名.成员方法名(参数值);   //通过对象名调用成员方法

同一类中直接调用:方法名(参数值);

再另外一个类中调用:类名称.方法名(参数值);



成员方法调用

没有static ,这是一个成员方法(实例方法,Instance Method)

需要调用成员方法就必须借助对象。


注意:

如果不创建对象,那么通过类名称只能调用静态方法。

如果创建了对象,那么通过对象名可以调用成员方法

通过对象名也可以调用静态方法,然而不推荐这么做



Lambda表达式冗余场景

在某些场景之下,Lambda表达式要做的事情,其实在另外一个地方已经写过了

那么此时如果通过Lambda表达式重复编写相同的代码,就是浪费。



方法引用的更优写法

在写Lambda表达式的地方写

方法引用:

如果Lambda表达式需要做的事情,在另一个类当中已经做过了,那么就可以直接拿过来进行替换Lambda

方法引用的写法:       


通过类名称引用静态方法的格式:

类名::静态方法名

方法引用的另一个方法,通过对象引用成员方法格式:

对象名::成员方法名



Stream流的更优写法

day10Code



Stream流式思想




获取Stream流的常用方法

java 8 当中的“流“其实就是Stream接口的对象

JDK提供了一个流接口,java.util.stream.Stream


如何获取流?

1.根据集合获取流:集合名称.stream();

2.根据数组获取流  :Stream.of(数组名称);



Stream流的map映射方法:

获取流之后,可以使用映射方法:map(用于转换的Lambda表达式)

映射:就是将一个对象转换成另一个对象,把老对象映射到新对象上



Stream流的filter过滤方法:

如果希望对流中的元素进行过滤,可以使用过滤方法

filter(能产生boolean结果的Lambda),如果参数Lambda产生了true,则要元素;如果产生了false,则不要元素 



Stream流的forEach方法:

如果希望再流中进行元素的遍历操作,可以使用forEach方法

forEach(Lambda表达式),意思是,对流当中的每一个元素都要进行操作

参数Lambda表达式必须是一个能够消费一个参数,而且不产生数据结果的Lambda

例如:

Lambda:  s -> System.out.println(s);

方法引用:  System::println



并发的Stream流

流当中的元素如果特别多,那么只有一个人在逐一,挨个儿处理,肯定比较慢,费劲

如果对流当中的元素,使用多个人同时并发处理,这就是并发

注意事项:

1.使用并发流的时候,到底有几个人进行同时操作呢?不用管,JDK自己处理

2.只要正确使用,就不会出现多个人抢到同一个元素的问题

3.如果已经获取了一个普通流,那么只要再调用一下parallel()方法也会变成并发流


总结:

1.直接获取并发流:.parallelStream()

2.已经获取了普通流,然后升级成为并发流:.stream().parallel()



模块化思想概述

你可能感兴趣的:(Java语法)