printf语句 (带格式的输出)

格式:System.out.printf("str",a,b,...);

eg.printf("%02d:%02d\n",hour,minute)

  • "%02d:%02d\n"用一个字符串表明输出的格式;
  • %表示格式说明的起始符号,不可缺少;
  • :为固定会输出的内容(例如本句对应时与分之间的:);
  • 0有0表示指定空位填0,如省略表示指定空位不填。;

输出样例 08:21

补充内容 printfの用法

private关键字

  • 只在这个类内部可以访问
  • 类内部指类的成员函数和定义初始化
  • 这个限制是对类的而非对对象的(同一个类的不同对象之间可以互相访问私有变量)

eg public static Fraction multiply(Fraction r)可以访问对象r中的私有变量

img

编译单元:一个源代码文件,是一个编译单元,一次对一个编译单元进行编译。
一个编译单元中可以有多个类,但只能有一个类的可见类型为public,且该类类名与文件名相同

if语句の小括号

我们都知道,在Java语言中,==表示比较,=表示赋值

有这样一段代码:

1
2
3
4
5
boolean m = false;
if ( m=false )
System.out.println("False");
else
System.out.println("True");

它的输出为True

if(m=false) 的执行顺序是:

  1. m=false 这个式子的返回值是m, 给m赋值
  2. if(m) 而这时的m为false,流程转到else执行,输出True。

由于if()的括号里必须是布尔类型,所以仅限Boolean定义的m可以使用上述方法噢

关于Java中length、length()、size()的区别

  • length不是方法,是属性,数组的属性;

    1
    2
    3
    4
    public static void main(String[] args) {
    int[] intArray = {1,2,3};
    System.out.println("这个数组的长度为:" + intArray.length);
    }
  • length()是字符串String的一个方法;可用于获得字符串的长度。

  • size()方法,是List集合的一个方法;在List的方法中,是没有length() 方法的;

  • 归根结底,几种方法最后均需依靠更为底层的length方法实现。

==equals

  1. 首先的区别是,equals 是方法,而 == 是操作符;
  2. 对于基本类型变量而言,没有equals方法,使用==比较,一般比较的是它们的值
  3. 对于引用类型变量,才有equals方法。该方法原是比较两变量在内存中的存放位置,由于String类中equals方法被重写,若是两变量存放位置不同,该方法会比较它们的值

一个很直观的实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
String a = "Hello World";
String b = new String("Hello World");
String c = b; //引用传递
System.out.println("a == b:" + a == b); //false
System.out.println("b == c:" + b == c); //true
System.out.println("a == c:" + a == c); //false
System.out.println("a.equals(b):" + a.equals(b)); //true
System.out.println("b.equals(c):" + b.equals(c)); //true
System.out.println("a.equals(c):" + a.equals(c)); //true

//最终的打印会是:
a == b:false
b == c:true
a == c:false
a.equals(b):true
b.equals(c):true
a.equals(c):true

因为 String b 通过 new 的方式已经开辟了新的堆内存,与a在Java内存里的存放位置不相同,所以第一个比较是false

final关键字

写滴好哇
final修饰的方法不能被重写,但可以被调用和重载。
final VS static
static作用于成员变量用来表示只保存一份副本,而final的作用是用来保证变量不可变。

static关键字

  • 在修饰变量的时候,static 修饰的静态局部变量只执行初始化一次,而且延长了局部变量的生命周期,直到程序运行结束以后才释放。(参见往年题T23A,考点考点!!)
  • static 修饰全局变量的时候,这个全局变量只能在本文件中访问,不能在其它文件中访问,即便是 extern 外部声明也不可以。
  • static 修饰一个函数,则这个函数的只能在本文件中调用,不能被其他文件调用。

++の研究

1
2
int i=5,j=10;
int k = i+++j; //k=15

exit、break、continue和return

System.exit(status) 终止当前正在运行的程序 status为0时程序正常执行结束退出,非零表示异常终止。
return语句必须返回一个值。返回的值要么与函数的返回类型相同,要么能进行隐式地转换为函数的返回类型。
return表示结束当前方法(包括所有循环)
break结束当前循环,不影响后面代码执行
continue结束此次循环,继续下一次循环

Object类

  1. Java中的所有类都直接或间接继承自Object,无论是否明确指明,无论其是否是抽象类。

ps:形参列表的作用是给成员变量赋初值,在构造函数的末尾,以一个冒号开始,变量之间以分号隔开,括号中放初始值

abstract

抽象类的定义,抽象方法的定义,抽象类的使用原则与相关规定

抽象方法是只声明而未实现的方法,即没有方法体{},举例

public abstract void getPersonInfo();

抽象类的使用原则

  • 抽象类必须有子类(abstract与final不能同时使用)。
  • 子类覆写抽象类所有的抽象方法(abstract与private不能同时使用)。
  • abstract关键字修饰方法,在直接子类中必须被实现或者重写(x) 直接子类可能还是个抽象类,不实现抽象方法。
  • 抽象类实例化对象,必须通过子类向上转型来实例化对象(抽象类无法直接实例化对象)。
  • abstract只能修饰类、方法、接口,且接口自带抽象属性。abstract不能修饰属性变量!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
//抽象类的标准操作,也是常用操作。

abstract class Person{
//姓名属性
private String name;
//普通方法
public String getName(){
return this.name;
}
public void setName(String name){
this.name=name;
}
//抽象方法
public abstract void getPersonInfo();
}

//子类继承抽象类
class Student extends Person{
public void getPersonInfo(){
System.out.println("I am a student");
}
}

public class Test{
public static void main(String[] args){
//实例化子类,向上转型
Person per = new Student();
//被子类所覆写的方法
per.getPersonInfo();
}
}

//运行结果:I am a student

throw&throws

1,throws用在方法声明后面,表示抛出异常,由方法的调用者处理,而throw用在方法体内,用来制造一个异常,由方法体内的语句处理。
2,throws是声明这个方法会抛出这种类型的异常,以便使它的调用者知道要捕获这个异常,而throw是直接抛出一个异常实例。

异常

Java的异常(包括ExceptionError)分为 可查的异常(checked exceptions)和不可查的异常(unchecked exceptions)
除了RuntimeException及其子类以外,其他的Exception类及其子类都属于可查异常。这种异常的特点是Java编译器会检查它,也就是说,当程序中可能出现这类异常,要么用try-catch语句捕获它,要么用throws子句声明抛出它,否则编译不会通过。
不可查异常(编译器不要求强制处置的异常):包括运行时异常(RuntimeException与其子类)和错误(Error)

基本数据类型和包装类型的区别——

  • 包装类是对象,拥有方法和字段,对象的调用都是通过引用对象的地址,基本类型不是;
  • 包装类型是引用的传递,基本类型是值的传递;
  • 声明方式不同,基本数据类型不需要new关键字,而包装类型需要new在堆内存中进行new来分配内存空间;
  • 存储位置不同,基本数据类型直接将值保存在值栈中,而包装类型是把对象放在堆中,然后通过对象的引用来调用他们,因此,包装类的效率会比基本数据类型的效率要低。
  • 初始值不同,比如:int的初始值为0、boolean的初始值为false,而包装类型的初始值为null;因此,Boolean b = null;是正确的
  • 使用方式不同,基本数据类型直接赋值使用就好,而包装类型是在集合,比如Collection、Map时会使用。

charの不同表现形式

char 是字符数据类型 ,是无符号型的,占2字节(Unicode码 ),大小范围 是0—65535 ; eg.char i = '1'
char是一个16位二进制的Unicode字符,JAVA用char来表示一个字符 eg. char m = (char)n;
所以:字符数据类型char,存储的内容是2个byte的二进制数。(√)

Java构造方法

  • 方法名必须与类名相同,一个类可以有多个构造方法
  • 可以有 0 个、1 个或多个参数
  • 没有任何返回值,包括 void
  • 默认返回类型就是对象类型本身
  • 只能与 new 运算符结合使用
  • 每个类都有构造方法,在创建一个对象时,至少要调用一个构造方法
  • 实例化类的属性

局部变量

  1. 类的方法中的变量
  2. 只在方法或语句块中可见
  3. 局部变量没有默认值,所以局部变量被声明后,必须经过初始化才可以使用
  4. 方法结束后,局部变量就会自动销毁
  5. 局部变量不可以是静态的
  6. 访问权限修饰符不能用于局部变量

实例变量:

  1. 定义在类中,方法体之外的变量
  2. 在对象创建时创建,在对象销毁时销毁
  3. 可以被类中方法、构造方法和特定类的语句块访问
  4. 实例变量具有默认值
  5. 可以被访问权限修饰符修饰
    img_3

类变量(静态变量):

  1. 独立于方法之外的变量,用static 修饰
  2. 无论一个类创建了多少个对象,类只拥有类变量的一份拷贝
  3. 随着类的加载而加载,随着类的销毁而销毁
  4. 优先于对象存在
  5. 被所有对象共享
  6. 可以直接被类名调用 ClassName.VariableName

计算

  • 不论有什么运算,小括号的优先级都是最高的,先计算小括号中的运算

  • 任何字符与字符串相加都是字符串,但是是有顺序的,字符串前面的按原来的格式相加,字符串后面的都按字符串相加

    1
    2
    3
    int x =10,y=5;
    System.out.println(x+y +""+x+y);
    //结果为15015

方法重载、方法重写(覆盖)

方法重载:

  1. 函数名相同,参数不同(参数数量,类型,顺序)的多个函数
  2. 函数重载不关心返回值类型,即返回值类型可以不同也可以相同
  3. 但是光返回值不同不是函数重载,是瞎写

方法重写(方法覆盖):

  1. 子类重写父类方法,要求方法名和参数类型以及返回值类型完全一样(参数不能是子类),返回值或异常比父类小或相同,访问修饰符比父类大或相同。
  2. 子类和父类的方法必须都是实例方法才会实现重写,若父类是静态方法,子类是实例方法或者相反都会报错,若父类和子类都是静态方法,那么子类会隐藏父类的静态方法,而不是覆盖。

继承 子类与父类

父类的东西子类都可以继承到,但如果父类某变量类型为private,子类不能直接对其进行操作,但可以通过父类的函数对其进行操作;在谁的函数中,所指的成员变量就是谁的;如果子类和父类中出现同名成员变量,函数在子类中则指子类的变量,反之亦然。
调用方法时,要注意方法本身是否可见!

将子类对象强转为父类对象,编译可以通过,但强转后的父类对象所拥有的父类中的方法是被子类覆盖的方法

方法调用机制:

  1. 父类中构造方法和成员方法中调用的方法必先去找本类中的方法(考虑形参
    类型),若没有则连编译都通不过。若有则再看子类中是否重写该方法
  2. 子类中构造方法和成员方法中调用的方法也先到本类中找,若有则直接用,
    若没有则再到父类中找
  3. 使用多态创建的子类对象在直接调用方法时必须先到父类中找是否
    有该方法,且必须考虑形参类型,找到后再去看子类中是否重写了该方法(必须是和父类中形参相同
  4. 若是单纯子类引用指向子类对象,调用方法时先在子类里面找是否有该方法(考虑形参类型),若没有,则再到父类中去找,若有(方法名和形参完全相同)则直接调用该方法,若没有,则再回到子类中看是否有形参不同的同名方法
  • 静态方法可以被子类重写,但两个静态方法各自属于各自的类,即当使用多态创建子类对象调用该静态方法时,由于是父类引用,所以会调用父类中的静态方法。若是子类引用指向子类对象调用该静态方法,则调用子类中的静态方法。
  • 被static 修饰的方法必然也可以重载
  • final可以用来修饰类,表明该类不得有子类;但是不得用于修饰抽象类和接口,更不得用于修饰抽象方法,即finalabstract必不可能同台出现 。
  • 注意区别 “多层” “多重”:java中允许“多层”继承,但不允许“多重”继承(多继承)
  • 同一个类中定义的构造方法可以相互调用,但只允许调用一个(this()必须出现在第一句,如果调用多个则会有不出现在第一句的this())
  • 一个Java文件中可以有多个类,但只能有一个用public修饰的类,每个类里都可以有一个main方法。因此一个java文件可以有多个main方法。
  • public修饰的类的类名必须与Java文件名一致,其他类名不做要求

多态变量

Java的对象变量是多态的,他们能保存不止一种类型的变量
他们可以保存的是声明类型的变量,或声明类型的子类的对象;
当把子类的对象赋给父类的变量的时候,就发生了向上造型
造型:把一个类型的对象赋给另一个类型的变量,子类对象可以赋值给父类的变量,但父类的变量不能赋值给子类的变量

总是记不住的变量类型

1
2
3
4
5
6
7
8
9
10
11
1.整型                         (一个字节占8位)
类型 存储需求 bit数 取值范围 备注
int 4字节 4*8 (32) -2^31~2^31-1
short 2字节 2*8 (16) -2^15~2^15-1
long 8字节 8*8 (64) -2^63~2^63-1
byte 1字节 1*8 (8) -2^7~2^7-1 = -128~127

2.浮点型
类型 存储需求 bit数 取值范围 备注
float 4字节 4*8 (32) 3.4028235E38 ~= 3.4*10^38
double 8字节 8*8 (64) 1.7976931348623157E308 ~=1.7*10^308

科学计数法需要用double类型表示
Double oD=3;(x) double oD=3; (√)

package

  • 为了更好地组织类,Java提供了包机制,包是类的容器,用于分割类名空间。如果没有指定包名,所有的示例都属于一个默认的无名包。
  • Java中的包一般均包含相关的类,java是跨平台的,所以Java中的包和操作系统没有任何关系,Java的包是用来组织文件的一种虚拟文件系统;
  • import语句并没有将对应的Java源文件拷贝到此处,仅仅是引用,告诉编译器有使用外部文件,编译的时候需要读取这个外部文件。
  • 定义在同一个包内的类可以不经过import而直接相互使用

文本文件&二进制文件

  • 文本文件是以不同编码格式显示的字符。当一个文件的扩展名为“txt”时,系统就认为它是一个文本文件。此外,处于特殊的目的,有些文本文件使用其它的扩展名。例如,计算机的源代码也是文本文件,它们的后缀是用来指明它的程序语言的。
  • File类是Java中对文件进行读写操作的基本类。(x)File类是对文件整体或者文件属性操作的类,例如创建、删除、查看文件等功能,不能操作文件内容,文件内容是用IO流操作的。

运算符与优先级

算术运算符 > 关系运算符 > 逻辑运算符 (! 大于 && 大于 ||)
结合性不是求值顺序,是优先与左、右哪边结对运算。
逻辑/位运算的【结合性】优先级都是:非、与、或
所以if(X || Y && Z) 相当于 if(X || (Y&&Z))

求值还是严格的从左到右。
先对X部分求值,代入c的值20 < 30求值为true,然后c自减为19。

这时||已注定为true,短路,Y、Z部分无需执行。

链表

  • 基础知识
  1. 链表是一种数据结构,在空间上不连续的存储结构,数据元素的逻辑顺序是通过链表中的引用连接次序实现的。
  2. 链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。
  3. 每个结点包括两个部分:①存储数据元素的数据域;②存储下一个结点地址的指针域。
  4. 每个链表都需要一个头结点(first或head)
  5. 链表可分为单向链表、双向链表、循环链表等。(一般考试只考单向链表)
  • 链表的节点类
1
2
3
4
5
6
7
8
9
10
11
public class Node {
Node next = null;//当前节点的next域,指向下一个节点
int data; //当前节点的数据域
public Node(int data){
this.data = data;
}
public Node(int data,Node next){
this.data=data;
this.next=next;
}
}
  1. 链表的节点类一般会有两个构造方法:①单纯的数据域的构造方法,指针为null;②除了指明数据域之外,并指明下一个节点在哪里;
  • 链表中常用方法的实现(头结点为head)
    1.在链表尾部添加节点
    尾结点特点:next==null,我们只需找到指针为null的节点,让该节点next域指向添加的节点,让添加的节点的指针指向null即可
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public void addNode(int data){
Node newNode = new Node(data);
//先判断链表是否为空
if(head==null){
head = newNode;
}
else{
Node cur = head;
while(cur.next != null){ //寻找尾结点
cur = cur.next;
}
cur.next = newNode;
}
}

// cur和head指向同一个地址,因此cur所做的任何修改即为对原链表的修改

ps:不管对链表进行何种操作,都需要对其是否为空进行判断。
2.在指定位置index后添加节点
①判断index是否合法;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public void addNode(int index,int data){
//计算当前链表大小
Node tp = head;
int cnt = 0;
while(tp !=null){
cnt++;
tp = tp.next;
}
//判断下标index是否合法
if(index<0 || index >= cnt){
System.out.println("Error Index");
return;
}
//判断是否在头结点插入
if(index==0){
head = new Node(data,head);
//让其变成一个新的头结点(data即为要插入的数据,其指针指向head)
}
else{
Node cur = head;
for(int i=0;i<index-1;i++){
cur = cur.next;
}
cur.next = new Node(data.cur.next);
}
}

3.删除数据域为data的节点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public void deleteNode(int data){
//首先判断链表是否为空
if(head==null)
return;
//判断头结点是否为要删除的节点
if(head.data==data){
head = head.next;
}
else{
Node cur = head;
while(cur.next.data != data && cur.next != null){
cur = cur.next;
}
if(cur.next == null) //说明到达链表尾部,未找到目标节点
return;
else
cur.next = cur.next.next; //删除目标节点
}
}

4、对链表节点进行排序,并返回排序后的新头结点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public Node linkSort(){ // 采用选择排序
Node cur = head;
while(cur != null){ // 外层循环控制当前已完成排序的位置
Node next = cur.next;
while(next != null){ //内层循环寻找未排序部分的最小值
if(cur.data > next.data){
int temp = cur.data; //交换节点的data值
cur.data = next.data;
next.data = temp;
}
next = next.next;
}
cur = cur.next;
}
return head;
}

选择题知识点

  1. Java中数组的下标只能是各种整数数据类型(即int类型)
  2. 异常:可以在方法定义中抛出异常而不是用catch语句块进行异常捕获(即用throws关键字抛出异常)
  3. 应该是先进入子类的构造函数,若在子类构造函数的第一行没有显示的调用父类的构造函数,则自动调用父类那个无参的构造函数。若已显示的调用了,则调用显示调用的构造函数,而不再调用父类其它的构造函数。
    注意:在没有显示调用的情况下,若父类中无构造函数,则调用父类默认的构造函数。若父类中有构造函数而没有无参的构造函数,编译时会报错。
  4. 子类不能继承父类的构造函数
  5. final 可修饰类、属性、方法,代表类、属性和方法是不可被继承的
  6. abstract是抽象的意思,在java中,规定只能修饰类或者方法,所以不能修饰属性。
  7. 接口的主要用途就是被实现类实现,一个类可以实现一个或多个接口,继承使用 extends 关键字,实现则使用implements关键字。
  8. 抽象类中不能有static,final,private修饰的方法
  9. 抽象方法必须在子类中实现(√) 抽象方法在子类中必须被实现(x)【大不了就还是个抽象方法呗】
  10. 数组是一种对象,不属于原生类
  11. 构造方法可以用public、private、protected修饰,但不能用static
  12. Java中,一个类不能继承多个类,但是一个接口可能继承多个接口。一个接口使用关键字extends来继承自其他接口 这个亚子public interface PersonBehavior extends SpeakBehavior, LaughBehavior {}
  13. 普通类不能包含抽象方法
  14. 作为调用父类构造器的super(),必须在子类构造函数的第一行,只能调用一次。但是普通的super就没有这种限制了。
  15. 一个变量可以保存其所声明的类型或该类型的任何子类型。
  16. Java不存在对象对对象的赋值(op语言均是如此,但c++例外)
  17. 类与类之间的关系称作耦合,耦合越低越好,保持距离是形成良好代码的关键。
  18. 父类引用可以指向子类对象 例如:Animal animal = new Cat(); ,即声明的是父类,实际指向的是子类的一个对象。
  19. 静态方法中不能引用非静态变量! 静态方法可以通过所在类直接调用而不需要实例化对象,非静态成员变量则是一个对象的属性,它只有在有实例化对象时才存在的,所以在静态方法中是不可以调用静态变量的!
  20. 静态方法里的变量是临时变量,只在静态方法里有效。在静态方法里定义的变量就是静态的了,不需加static
  21. 构造方法没有任何返回值,包括 void. 默认返回类型就是对象类型本身. 只能与 new 运算符结合使用.
  22. Java会自动给没有构造方法的类创建一个无参的构造方法;构造器可以重载,并可以通过this()super()相互调用
  23. 所有的Interface继承了Object类这句话是不对的,应该说是所有的Interface继承了Object接口
  24. Java中所有的可不检测(unchecked)异常都来自RuntimeException类或其子类。
  25. main方法的形式参数为字符串数组
  26. Java中所有的可不检测(unchecked)异常都来自RuntimeException类或其子类。(√)
  27. 静态方法中不能有thissuper ,因为static 属于类的范畴,this 和 super属于对象的范畴。同样静态方法中也不允许出现将成员变量赋值给局部变量的操作
  28. 方法的局部变量不允许被static 修饰
  29. 权限修饰符只能修饰成员变量和成员方法,不能修饰局部变量
  30. this()super()的本质是构造方法,一个构造方法中只能有一个thissuper
  31. 成员方法中不允许有this()super()
  32. static关键字不能修饰普通类,但可以修饰内部类
  33. final修饰的类不能被继承;final修饰的方法不能被重写、但可以重载。
  34. 定义多维数组,第一维数组的大小必须初始化,其他的不必初始化 int[][][] arr = new int[3][][];但是使用时必须先对要使用的其他维度的数组进行大小初始化才可以赋值

写程序题常犯错误&实用方法集锦

  1. 换行符\t等,注意反斜杠方向;
  2. 判断某字符串内是否包含某字符 str.contains("") str.indexOf("")(注意:该方法返回一个int值,若值为-1,则不包含该字符,反之则包含)
  3. String 与 int 的相互转换 int i = Integer.phaseInt(str); String str = i +"";
  4. Java substring() 方法获取字符串的子字符串 Str.substring(4, 10) 【包括起始索引,不包括结束索引】,如果只有一个数字,则表示返回从该索引开始的字符串
  5. 字符串大小比较————compareTo()方法str1.compareTo(str2);其返回的是一个int类型值。 若Str1等于参数字符串Str2字符串,则返回0; 若该Str1按字典顺序小于参数字符串Str2,则返回值小于0;反之返回值大于0.
  6. return的内容最后写,先处理完异常和finally,注意for循环的次数!!有坑