循序渐进学java

/-matool API查询网站

重点内容:

第一阶段:

变量:数据类型

运算符:二进制

控制结构:循环

数组排序和查找:数组

面向对象编程:成员方法,成员方法传参机制,构造器

面向对象编程(中级):封装,继承,多态

第二阶段:

面向对象编程(高级):类变量和类方法,接口,内部类

Exception:异常体系图,异常处理

常用类:string,stringbuffer,stringbuilder

集合:

泛型:自定义泛型

线程:线程使用,Synchronized,互斥锁

IO流:输入流,输出流

开发注意事项:

1一个源文件中最多只能有一个public类,其他类的个数不限

2如果源文件包含一个public类,则文件名必须按该类名命名

3.一个源文件中最多只能有一个public类。其它类的个数不限,也可以将main方法写在非public类中,然后指定运行非public类,这样入口方法就是非public的main方法

/r为回车:回车后光标会回到“韩”字前,然后“韩顺”被“北京”代替

使用tab键,实现缩进,整体右移。Shift+tab整体左移。

相对路径和绝对路径:

加号的说明:

两边都是数值型的时候做加法运算,左右两边有一方为字符串时做拼接运算

基本数据类型:

+byte

使用long类型时,需要在变量后面加一个‘l’或“L“

例:long a = 10l;

Java默认浮点型常量为double型,因此在使用float型时需要在变量后面加上l或L

例:floa a = 1.1l;

浮点型可以写成.123 等价于0.123

对于运算结果时小数的进行判断时,应该用两个数的差值的绝对值,在某个精度范围内判断。

不同的字符编码表之间有所不同:

ASCII编码表:一个字符一个字节

Unicode编码表:字母和汉字都占用两个字节(最多编码2的16次方个字符)

utf-8:字母一个字节,汉字三个字节

等等。

布尔类型(boolean):赋值只能为true/false

在将精度(容量)大的数据类型转换成精度(容量)小的数据类型时会报错。

(Byte,short)和char之间不能相互转换,也不能自动转换

Byte,short,char之间或者同类型之间进行运算时,会转换为int类型。

Boolean不参与类型的自动转换。

字符串和其它数据类型之间的转换:

其它类型转字符串:+“”

字符串转其它类型:

取模:a % b =a-a/b*a;

结果的正负值要取决于a的负号。

重点:

关系运算符的运算结果为布尔类型:即ture或false

短路与:&& 逻辑与:&

对于短路与,如果第一个条件为假,则后面的条件不再判断,即不执行,效率高

对于逻辑与,如果第一个条件为假,后面的语句仍会执行

短路或:|| 逻辑或:|

效果同短路与和逻辑与

^:逻辑异或

复合赋值运算符会进行类型转换

byte b = 3;

b +=2;等价于b = (byte)(b+2);

输入的实现:

1引入java.util.Scanner,java.util下的Scanner类

2.创建一个类的对象,new创建对象

Scanner myScanner = new Scanner(System.in);

3.接收

String name = myScanner.next();输入为字符串类型

int age = myScanner.nextInt();输入为整形

double salary = myScanner.nextDouble();输入为浮点型

四种进制:

二进制:以OB或Ob开头

八进制:以数字0开头

十六进制:以OX或Ox开头 ,并且A-F不区分大小写

按位与:&

按位或:|

按位异或:^

按位取反:~

位运算符:

>>算数左移:地位补0

<<算数右移:高位补符号位

>>>逻辑右移:地位溢出,高位补0

没有逻辑左移

switch:返回类型必须是byte,short,int,char,enum,String类型之一。

case:值必须为常量或者常量表达式

break后面加标签:可以表示终止某个循环,类似于goto

判断两个字符串:推荐第二种

如:String name;

Name.equals(“字符串内容”)或”字符串内容”.equals(name)

数组:

数组类型[ ] 数组名 ([ ])= new 数组类型[个数]

double[] score = new double[5];

double score[];

score = new double[5];

数组赋值:arr2是arr1的一份拷贝,当arr2改变时,arr1也改变

冒泡排序:优化:j初始值为1,增加count变量,若执行一次交换则count增加,若count在循环后为0则提前终止循环。

动态开辟二维数组空间:

面向对象(基础):

对象中的整型放在堆区,字符串类型放在方法区中的常量池。

过程:

1先加载类信息(属性和方法信息,只会加载一次)

2在堆中分配空间,进行默认初始化

3把地址赋给用类创建的变量,变量指向对象

4.进行指定初始化

方法重载:减轻记名麻烦

要求:方法名相同,形参的类型或个数或顺序不同。

注意:返回类型不同不能构成重载。

可变参数,写法(变量类型... 变量名)

可以接受0-多个参数,此时的变量名相当于数组名,可以用变量名.length获得参数个数,用变量名[i]访问每个变量。

细节:

可变参数的实参可以为数组,即直接传入一个数组。

可以同时存在普通类型的参数和可变参数,但是可变参数必须在最后。

一个形参列表中只能出现一个可变参数。

作用域细节:

属性和局部变量可以重名,访问时遵循就近原则。如:

此时name的值为“king”

全局变量可以加修饰符

局部变量不能加修饰符

构造方法/构造器:完成对新对象的初始化,类似于构造函数

细节:

一个类可以定义多个构造器,即构造器重载

This指针:当构造方法中的形参的类的对象名字相同时,可以在对象前加this.来区分

在一个构造器中访问另一个构造器时(本类),需要使用this(参数列表)

注意:需要将this语句放在第一条语句,只能在构造器中使用。

在需要获取数组的最大值时,为了避免传入的数组为空值,或者数组地址为null时,需要加上判断,当地址为null时,arr.length语句会报错。

直接new 类名(),此方法只创建一个对象,而没有返回,属于匿名对象,匿名对象在使用后,就不能使用。

IDEA中的快捷键:

Ctrl+D 删除当前行(自己配置)

Alt+/ 补全代码

Ctrl+alt+l 格式化代码

Alt+r 运行程序(自己配置)

将光标放在方法上,ctrl+B(或鼠标左键)可以定位到方法

模板快捷键:

Fori,输出for循环

Sout,输出System.out.println语句

创建不同的文件夹来保存类文件

方法如下:

命名规则:不能以数字开头,不能是关键字或保留字。

命名规范:com.公司名.项目名.业务模块名

如:

Arrays.sort(数组名),对数组进行升序排列。

Package的作用是声明当前类所在的包,需要放在类(或者文件)的最上面。

类只能用public和默认来修饰。

类的成员方法和属性可以用四个来修饰。

封装:

可以隐藏实现细节

可以对数据进行验证,保证安全合理

实现:

将属性私有化

提供一个公共的set方法,用于修改私有属性的值

提供一个公共的get方法,用于获取私有属性的值

构造器也同样需要对数据进行检测,因此可以把set方法写入构造器中,实现对数据赋值的同时完成验证。

继承:

可以解决代码复用。

基本语法:

class 子类(派生类) extends 父类(基类){}

细节:

子类必须调用父类的构造器,完成对父类的初始化

子类在调用构造器时,会自动调用父类的无参构造器,super语句(被隐藏)

若父类中无无参构造器,则需要用super语句指定构造器

super()和this()都只能放在构造器第一行,因此这两个方法不能共存在一个构造器。

Object类时所有类的基类

父类构造器的调用不限于直接父类!将一直追溯到Object类,即父类的父类的无参构造器也会被调用等。

Java中是单继承机制,即一个类只能继承一个,可以用A继承B,B继承C,来实现A同时继承B和C。

继承访问:

此时aa.name的值为大头儿子,aa.hobby的值为旅游:以此方法在访问变量时,会从当前类开始寻找,若当前类没有,会依次往上寻找,直到找到为止或报错。

此时aa.age会报错,在Father类中有age但是没有权限,不会再往上寻找。

Super的使用:(访问父类)

super.语句,访问父类属性和方法,private属性除外

访问父类构造器

语句:super();

方法重写(覆盖):

实现条件:子类和父类的方法,参数,方法名均相同。此时子类的方法覆盖父类的方法。

1返回类型可以相同,或者子类的返回类型是父类返回类型的子类。如:

String是Object的子类

2子类方法不能缩小父类方法的访问权限。

错误示例:子类是protected,父类是public。

多态:

方法的多态:体现在方法的重载和重写

对象的多态:

一个对象的编译类型和运行类型可以不一致。

编译类型看定义时 = 号的左边,运行类型看 = 号的右边

animal1的编译类型时animal,运行类型时cat。

此时animal1.cry()相当于cat.cry(),因为animal的运行类型时cat。

重新指定后:

animal1的编译类型依然是animal,运行类型变为dog。

细节:

1向上转型:父类的引用指向了子类的对象。如上图举例。

2向下转型:

animal可以通过强转再次变成cat类型,因为animal本身在编译后为cat类型,但是不能转换成dog类型。

属性没有重写之说!属性的值看编译类型,如下图输出结果为10.

Instaniof语句,用于判断对象的运行类型是否是XX类型或其子类型。

动态绑定机制:

1当调用对象方法的时候,改方法会和该对象的内存地址/运行类型绑定

2当调用对象属性时,没有动态绑定机制,哪里声明哪里使用

多态数组:

Object类:

==运算符:判断两个值是否相等,或是两个地址是否相同

equals是Object类中的方法,只能判断引用类型地址

查看方法源码:ctrl+左键

注意:

在Object子类中往往重写改方法,用于判断内容是否相等。

HashCode方法:

1提高具有哈希结构的容器的效率

2两个引用,如果指向的是同一个对象,则哈希值肯定是一样的,如果不是,则哈希值肯定不一样。

3哈希值主要根据地址号来,但是不完全等价于地址

Tostring方法:

方法重写后:把对象的属性输出,也可以自己修改

直接用sout输出一个对象等价于sout 对象名.toString

Debug断点调试:可以在调试过程中加断点

F8逐行执行

F7跳入方法(查看方法)

Shift+F8跳出方法

F9直接跳到下一个断点

零钱通:

日期显示:

类变量:

用static修饰的变量,是类共有的变量,可以通过类名来访问。同时需要遵守访问修饰符的权限。

类方法和类变量相似。

细节:

类方法中不能使用和对象有关的关键字,如this和super。

类方法只能访问静态变量或静态方法。

要在静态方法中访问,非静态方法或变量的话,可以通过在静态方法中new一个类,通过类访问非静态成员。

main方法:

由java虚拟机调用,而虚拟机所在为不同类,因此为public

Java虚拟机在执行main方法时,不必创建对象,所以为static

Java执行的程序,参数1,参数2,参数3,作为三个字符串数组传入args数组中

代码块:

(修饰符(static)){

代码

}(;)

代码块在构造器被调用时优先执行。

当有static修饰时,代码块随着类的加载而执行,并且只会执行一次

普通代码块:在对象创建时执行(new)

类的加载:在创建对象实例时(new)

创建子类对象实例,父类也会被加载(父类先加载)

使用类的静态成员时

创建对象时:在一个类中调用顺序:

(1)使用new创建对象之后,静态代码块和静态属性初始化调用的优先级一样,哪个在前先调用哪个,如上图先调用静态代码块。多个静态代码块和多个静态属性初始化的调用顺序同样。

(2)普通代码块和普通对象初始化,顺序同上

(3)调用构造方法

构造器代码顺寻:

(1).父类构造器

(2)本类代码块

(3)本类构造器代码

总结:先执行静态(先父类后子类),再普通(先父类后子类)。

静态代码块只能调用静态成员,普通代码块可以调用任意成员。

单例模式-饿汉式:

1将构造器私有化

2在类的内部直接创建

3提供一个公共的static方法,返回对象

缺点:创建了对象但是没有使用,造成资源浪费

单例模式-饿汉式:

1构造器私有化

2定义一个static静态对象

3提供一个public的static方法,可以返回一个对象

4当用户使用getInstacnce时才返回对象,再次使用时返回同一个对象。

final关键词:

1可以用来修饰类:使类无法被继承(不希望被其中方法被重写)

2修饰方法,使方法无法被改写

3修饰属性,使属性无法被修改

4修饰局部变量,使无法被修改

细节:

1被final修饰的变量,需要在进行初始化,如在定义时,通过构造器,通过代码块

如果还有static修饰,则不能在构造器中赋值(代码块为静态)

2.final不能修饰构造器

3..final和static搭配使用,效率更高,不会导致类加载

4.包装类都是final类型,如String

抽象类:

当父类的一些方法不能确定时,用abstra修饰该方法。

  1. 用abstra修饰的方法没有方法体

  1. 抽象类不能被实例化(不能通过new的方式创建)

  1. 抽象类可以没有抽象方法,有抽象方法的类必须是抽象类

  1. abstra只能修饰类和方法

  1. 抽象类本质还是类,可以有任意成员

  1. 当一个类继承抽象类后,它本身必须是一个抽象类或者实现父类中所有的抽象方法

  1. 抽象方法不能被private,final,static关键词修饰

接口:

interface 接口名{}

class 类名 implements 接口{

自己的属性

自己的方法:

必须实现的接口的抽象方法

}

细节:

  1. 接口不能被实例化(即new)

  1. 接口中的方法都是public方法,抽象方法可以不用abstra修饰

  1. 一个普通类实现接口,必须将改接口所有方法实现,可以使用alt+enter

  1. 抽象类去实现接口时,可以不实现接口的抽象方法

  1. 一个类可以实现多个接口

  1. 接口中的属性都是public static final 修饰符

  1. 接口可以继承接口,不能继承类

  1. 接口的修饰符只能是public或者默认,和类相同

接口可以解决单继承的问题

内部类:

  1. 局部内部类:

即在类中的一个方法中的类,该类可以直接访问外部类所有的成员(包括私有),不能使用修饰符(本质上是局部变量),但是可以用final修饰

作用域:仅仅在定义它的方法或代码块中。

外部类在方法中可以创建内部类对象,然后调用成员

当外部类和内部类的成员重名时,访问时默认遵循就近原则,可以通过外部类.this.成员,来访问

匿名内部类:

是一个类,同时是一个对象。是一个局部变量。

作用:简化开发

匿名内部类的本质是一个匿名类继承一个类或者实现一个接口

第二个演示表示匿名内部类是一个对象。

匿名内部类可以当作实参直接传递

创建内部成员类的方法:

2.

静态内部类:

是类的成员,遵循相同的访问规则。

枚举:

将构造器私有化,删掉set方法,将定义常量对象写在前面。

细节:

创建枚举对象时,自动继承了Enum类。

成员必须放在前面,且用逗号隔开,最后一个用分号。

如果调用的构造器是无参时,“()”可以省略。

Enum的成员方法:

name()返回成员名称

ordinal()返回成员序号(从0开始)

values()返回成员数组

可以通过增强for循环来实现遍历

valueOf(“常量名”),在枚举中寻找该常量名

常量1.compare To(常量2),返回得到常量1的编号减常量2的编号。

注解:

如:重写方法上的@Override

只能用在方法上,可以删掉,加上后编译器会检验方法是否被重写。

@Deprecated

可以修饰方法,类,字段,参数等到,用于做版本升级过渡

@SuppressWarnings

用于抑制警告,可以使用@ SuppressWarnings({“all“})抑制所有警告,也可以换成其它类型用于抑制相应类型的警告。

异常处理:

当程序出现一个异常后,可以让程序继续向下执行

使用ctrl+alt+t对可能出现异常的代码块进行异常处理。

细节:

当异常发生时,异常后面的代码不再执行,直接跳入catch代码块中

如果异常没有发生,则catch代码块不执行

finall代码块无论如何都会执行

可以没有catch,只有try和finally,此时若发生异常,程序会在执行完finally后结束。

Finally代码块必须执行,虽然在catch中返回3

Throws:

Throws的对象可以是异常类型本身也可以是它的父类

子类在重写父类的方法时,抛出的异常类型要么和父类一致,要么是父类所抛出异常的子类异常

包装类:

精度提升,三元运算符是一个整体

包装类的转换

包装类中的方法:

String类

String类有很多构造器:

用finally修饰的变量指向的地址不可改变。

当常量池中有变量时

String字符串特性:

该语句创建了两个对象(若常量池中无haha)

说明:String时一个finally类,其内容不可改变。

编译器会优化:判断创建的常量池对象是否有引用的指向

等价于 Sting a = “helloabc”;

String 中的intern方法:

如果池中有“s1+s2“字符串,则返回该字符串的地址,若没有则创建一个该字符串

常用方法:

示例:如果找不到,则返回-1;第一次出现的位置。可以找字符串

从下标6开始截取字符串

前闭后开截取字符串

示例:

注意:原字符串没有被替换

StringBuffer:

直接父类:AbstractStringBuilder

父类中有属性 char[] value 不是final类型

StringBuffer是一个finally类,不能被继承

String转StringBuffer

StringBuffer转String

StringBuffer中的方法:

如果要对String进行大量修改,就不要使用String,考虑StringBuffer,如果是单线程同时考虑StringBuilder

Math方法:

round为四舍五入保留整数

Arrays类:

如果传入的值为负数,则会报错

System方法:

System.exit(0)

0表示程序正常退出

Src:原数组

0:从原数组开始拷贝的位置

Dest:目的数组

0:从目的数字开始拷贝的位置

处理大数和需要保持高精度计算时使用

Date:

Calendar:

Local:

集合:

ArrayList演示:

迭代器:

List接口:

  1. 集合中的元素有序,且可以重复

  1. 每个元素都有对应的索引

  1. 可以根据其索引号来获取元素

ArraysList:

1.ArrayList基本等同于vector,效率高,但是不安全

2.ArrayList中维护了一个Object类型的数组

Transient表示该属性不会被序列化

  1. 当创建ArrayList对象时,如果用的是无参构造器,则初始容量为0,第一次添加时数组扩容为10,如果需要再次扩容则扩容为当前容量的1.5倍。

  1. 如果使用指定大小的构造器,则在需要再次扩容则扩容为当前容量的1.5倍。

Vector:

  1. 底层依然是一个可变的数组

  1. 安全,但是效率不高

  1. 如果是无参,则在第一次添加后扩容为10,以后每次需要扩容为当前的2倍

ArrayList和LinkList都是不安全的

Set接口:

  1. 无序,没有索引

  1. 不允许重复元素

虽然取出的顺序不是添加的顺序,但是顺序是固定的。

可以用迭代器和增强for循环进行遍历,不能用普通for循环,因为没有get方法

HashSet底层是hashmap,是一个数组加链表的结构

  1. 再添加一个元素时,先得到hash值,然后转换成索引值。

  1. 根据索引值存放到数组对应的位置

  1. 若对应的位置已有元素,则调用equals方法与元素进行比较,如果相同则放弃添加,如果不相同则添加到最后。

  1. 当一条链表的元素个数超过8以后,并且table的大小>=64,就会进行树化。

  1. 当添加的元素个数大于阈值(当前数组大小的0.75倍,数组初始化大小为16)时,数组会进行扩容,扩大为原来的两倍,同时阈值也会扩大为2倍。

Map:

  1. 保存具有映射关系的数据

  1. Key和value可以是任何引用类型的数据,会封装到HashMap$Node对象中

  1. Key不允许重复,否则会覆盖

  1. Key和value都可以为null,但是key只能有一个,value可以有多个

5.k-v最后是HashMap$Nodenode = newNode(hash,key,value,null)

6.为了方便程序员遍历,还会创建EntrySet集合,该集合存放的元素的类型Entry,而一个Entry对象就有k,v,EntrySet<Entry<K,V>>

7.entrySet中定义的类型是Map.Entry,但是实际上存放的还是HashMap$Node,因为Node实现了Map.Entry

8.当把HashMap$Node对象存放到EntrySet就方便我们的遍历,因为Map.Entry提供了重要的方法:getKey和getValue

遍历方式:

HashTable:

  1. 键和值都不能为空,否则会抛出异常

  1. 使用方法基本和HashMap一样

  1. 每次扩容变为原容量的2倍+1,初始容量为11

Properties:

Treeset:有序,可以自定义

自定义比较器的作用:决定了数据的顺序,同时决定了数据能否被添加进去的规则,如上图:以长度升序排列字符串,如果有长度相同的情况则无法添加

Collection工具类:

下面的代码会报错,原因是在底层要尝试把加进去的对象转换成Comparable,对象没有实现comparable接口,因此会有转换类型的异常。

泛型:

1.为了约束数据类型

2.省去转型的麻烦

约束加入的类型只能为Dog

不用再向下转型

用来解决数据的安全性问题

作用:可以在类声明时通过一个表示表示类中的某个属性,或是某个方法的返回类型,或是参数类型

泛型使用细节:

1.泛型指向的数据类型要求是引用类型,不能是基本数据类型。如:

Int是基本数据类型

2.在指定泛型后,传入的数据类型可以是其本身。也可以是其子类

3.使用形式:后面的括号里的内容可以省略,推荐这种写法

4.如果没有指定泛型,则默认为Object类型

自定义泛型:

1.泛型标识符可以有多个,一般都是大写字母

2.普通成员(属性,方法)可以使用泛型

3.使用泛型的数组不能初始化(因为数组在new时,不能确定类型,因此无法开辟空间)

4.静态方法中不能使用泛型(静态方法在类加载时,对象还未创建,无法完成初始化)

自定义泛型接口:

1.接口中,静态成员不能使用泛型

2.泛型接口的类型,在继承接口或实现接口时确定

3.没有指定类型,默认为Object

泛型在方法中的使用:

1.泛型方法可以定义在普通类中,也可以定义在泛型类中

2.当泛型方法被调用时,类型会确定

3.泛型方法,可以使用类声明的泛型类型,也可以使用自己声明的泛型

4.注意泛型方法和方法使用了泛型的区别

形如:

R要在参数中使用,在调用方法时,会根据传入的参数的类型,变化R的类型

Say1方法使用了泛型

Say2方法是泛型方法,同时也使用了泛型

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值