目录
4、String、StringBuilder和StringBuffer
3、HashSet、LinkedHashSet、TreeSet区别
4、HashMap、LinkedHashMap、TreeMap区别
一、Java入门
1、Java语言的特点
- 面向对象
- 安全性
- 多线程
- 简单易用
- 开源、跨平台
Java语言风格像C和C++,但是它抛弃了一些C++的缺点,比如指针(容易引起错误)、多继承等,同时增加了垃圾回收机制,可以释放内存空间,解决了管理内存空间的问题。
2、JRE和JDK区别
JVM:Java虚拟机;
JRE:Java的运行环境,包含了JVM和Java的核心类库(API);
JDK:Java开发工具,包含了JRE;
总结:只需安装JDK就可以,包含了Java的运行环境和虚拟机。
3、常见运算符
算术运算符:+ - * / %
/:整除 %:对模取余
关系运算法:
== 就是判断左边跟右边是否相等,如果成立就是true,如果不成立就是false != 就是判断左边跟右边是否不相等,如果成立就是true,如果不成立就是false > 就是判断左边是否大于右边,如果成立就是true,如果不成立就是false >= 就是判断左边是否大于等于右边,如果成立就是true,如果不成立就是false < 就是判断左边是否小于右边,如果成立就是true,如果不成立就是false <= 就是判断左边是否小于等于右边,如果成立就是true,如果不成立就是fals 逻辑运算符:
&:逻辑与(而且)
两边都为真,结果才是真,只要有一个为假,那么结果就是假。
|:逻辑或(或者)
两边都为假,结果才是假,只要有一个为真,那么结果就是真。
^:异或
如果两边相同,结果为false,如果两边不同,结果为true
!:取反
短路逻辑运算符:
&&:
运算结果跟&是一模一样的,只不过具有短路效果。
||:
运算结果跟|是一模一样的。只不过具有短路效果
三元运算符:关系表达式 ? 表达式1 :表达式2 ;
规则:如果关系表达式的值为真,那么执行表达式1;如果关系表达式的值为假,那么执行表达式2。
4、隐式转换规则
概念:自动类型提升。把一个取值范围小的数据或变量,赋给一个取值范围大的变量。不需要额外写代码实现,是程序自动完成。(理解为:小给大,直接给)
规则:
-
取值范围小的,和取值范围大的进行运算,小的会先提升为大的,再进行运算。
-
byte、short、char三种类型的数据在运算的时候,都会直接先提升为int,然后再进行运算。
从小到大关系:byte short int long float double
5、不同循环使用场景
for:知道循环次数
while:知道结束条件
do-while:与while相当,但是先执行,后判断
switch:有多个结果,需要匹配的时候。JDK12以后可以简化代码格式:
switch (变量) {
case 1, 2, 3, 4, 5 -> System.out.println("输出");
case 6, 7 -> System.out.println("输出");
default -> System.out.println("输出");
}
break:不能单独存在的。可以用在switch和循环中,表示结束,跳出的意思
continue:不能单独存在的。只能存在于循环当中。表示:跳过本次循环,继续执行下次循环。
6、方法
方法(method)是程序中最小的执行单元,需要创建以后调用 才能执行
二、面向对象
1、面向对象三大特性
封装、继承、多态
封装:简单来说就是将数据隐藏,不被外界访问。需要特点方法去访问。
getXX(XX表示成员要访问变量的名字)用来读取成员变量,另一个是setXX()用来对变量赋值
Java中类中成员的属性有:public, protected, <default>, private,这四个属性的访问权限依次降低。
继承(extends):继承是类与类的关系,子类拥有父类全部方法,但都是直接或间接继承的Object类(我愿称他为祖先类)
注意:Java没有多继承,只有单继承。被final修饰,或private修饰的无法被继承
多态:同一方法可以根据发送对象的不同而采用多种不同的行为方式。
注意:多态存在三个必要条件:继承,重写,父类引用指向子类对象
2、接口与抽象类的区别
No. | 区别 | 抽象类 | 接口 |
1 | 定义关键字 | abstract class | interface |
2 | 组成 | 常量、变量、抽象方法、构造方法 | 全局常量、构造方法 |
3 | 关系 | 可以实现多接口 | 不能继承抽象类,可以继承接口 |
4 | 类型 | 可以用各种权限类型(public、private等等) | 只能public |
5 | 关键字 | extends | implement |
6 | 局限性 | 一个子类只能继承一个抽象类 | 可以实现多个接口 |
由此可以看出,当可以在抽象类和接口都能使用的情况下,推荐使用接口,避免继承的局限性。
3、重载与重写
重载:一个类定义多个方法名相同,参数不同的方法。传递相应的参数个数、类型,便调用那个相应的方法。
public static int A(int a);
public static int A(int a,int b);
public static int A(int a,int b.,int c);
重写:子类重写父类方法,代替父类方法的内容。
4、String、StringBuilder和StringBuffer
String类:
- 字符串不可变,在创建后不能被改变
-
虽然 String 的值是不可变的,但是它们可以被共享
StringBuilder:可以看出一个容器,创建后内容可以改变,一般在拼接字符串和反转字符串会用到。
StringBuffer:可以直接在字符串对象本身上进行操作。
选择:字符串定义:String;频繁修改字符串:StringBuilder;多线程使用共享变量时:StringBuffer
5、成员变量与局部变量的区别
区别 | 成员变量 | 局部变量 |
类中位置 | 类中,方法外 | 方法内、方法声明 |
内存位置不同 | 堆内存 | 栈内存 |
初始化值不同 | 有默认值 | 无默认值 |
生命周期 | 随对象创建存在,消失而消失 | 随着方法调用存在,方法结束运行就消失 |
作用域 | 整个类 | 当前方法 |
6、==与equals的区别
==号的作用:
- 比较基本数据类型:比较的是具体的值
- 比较引用数据类型(如String):比较的是对象地址值
equals的作用:
可以直接比较字符串内容是否相同
7、字符串常量池
为提高性能与减少开销,JVM中有一个内存叫做常量池。顾名思义,就是存储常量的内存空间
字符串常量池便是用于保护字符串常量的内存空间。在JDK8以后,字符串常量池从方法区移入到了Heap堆区。
三、集合内容
1、List、Set、Map定义
List集合:有序、可重复、可排序、有索引
Set集合:无序,不重复、可排序(单独使用TreeSet)、无索引
Map:双列集合,键值对形式,键不可重复,值可重复
2、Collection和Collections的区别
Collection:集合接口,提供了对集合进行基本操作的方法,List,Set等都是他的子类
Collections:集合的工具类,包含了许多API
3、HashSet、LinkedHashSet、TreeSet区别
- HashSet:无序、不重复、无索引
- LinkedHashSet:有序、不重复、无索引
- TreeSet:可排序、不重复、无索引(红黑树结构)
3、哈希表结构、红黑树结构
哈希表:哈希表是一种根据关键码去寻找值的数据映射结构,类似于查字典,通过关键字与索引去找。
红黑树:是一种二叉查找树,具体结构较为复杂,可以去百度自行搜索。
4、HashMap、LinkedHashMap、TreeMap区别
HashMap:
- HashMap是Map里面的一个实现类。
- 无序、不重复、无索引
- HashMap跟HashSet底层原理样的,都是哈希表结构
LinkedHashMap:
- 由键决定:有序、不重复、无索引。
- 这里的有序指的是保证存储和取出的元素顺序一致
- 原理:底层数据结构是哈希表,只是每个键值对元素又额外的多了一个双链表的机制记录存储的顺序。
TreeMap:
- TreeMap跟TreeSet底层原理一样,都是红黑树结构的。
- 由键决定特性:不重复、无索引、可排序
- 可排序:对键进行排序。
- 注意:默认按照键的从小到大进行排序,也可以自己规定键的排序规则
5、重写equlas方法也要重写HashCode方法的原因
因为hashcode会返回一个int,这个int类型的整数作用是去找对象在哈希表中的索引。如果两个对象相等,那么hashcode就相同。若相等,两个对象就分别调用equlas,返回true。但是也有不相等的情况,所以eqluas重写的时候,也要重写hashcode。
四、多线程、异常与IO流
1、Java的常见异常
-
NullPointerException 空指针异常
-
ArrayIndexOutOfBoundsException 数组下标越界异常
-
SQLException SQL异常
-
ArithmeticException 数学运算异常
-
ClassNotFoundException 指定类不存在
-
FileNotFoundException 文件未找到:一般用在IO中
-
NoSuchMethodException 方法不存在
2、异常处理机制
异常分为运行时异常(RuntimeException)和编译时异常,而它们都是Exception异常的子类。
Java通过try、catch、finally、throw、throws这几个关键字来处理Java当中的异常。
try...catch用来捕获异常
throw throws用来抛出异常
finally是无论是否有异常,里面的代码都要实现
3、throws和throw
throw:用在方法体内,表示抛出异常,由方法体内处理
throws:用在方法声明后面,由调用者处理异常
4、并发与并行
- 并发:指两个或多个事件在同一个时间段内发生。
- 并行:指两个或多个事件在同一时刻发生(同时发生)
5、线程与进程
- 进程:是指一个内存中运行的应用程序,每个进程都有一个独立的内存空间,一个应用程序可以同时运行多 个进程;进程也是程序的一次执行过程,是系统运行程序的基本单位。
- 线程:线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程。一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序。
6、线程同步、同步代码块、Lock锁
synchronize(同步锁){
需要同步的代码
}
- 锁对象可以是任意类型。
- 多个线程对象要使用同一把锁
Lock锁:
同步代码块、 同步方法具有的功能 Lock 都有 , 除此之外更强大 , 更体现面向对象。Lock 锁也称同步锁,加锁与释放锁方法化了,如下:public void lock() : 加同步锁。public void unlock() : 释放同步锁。
7、线程状态
线程状态
|
导致状态发生条件
|
NEW(
新建
)
|
线程刚被创建,但是并未启动。还没调用
start
方法。
|
Runnable(
可
运行
)
|
线程可以在
java
虚拟机中运行的状态,可能正在运行自己代码,也可能没有。
|
Blocked(
锁阻
塞
)
|
当一个线程试图获取一个对象锁,而该对象锁被其他的线程持有,则该线程进入
Blocked
状态;当该线程持有锁时,该线程将变成Runnable
状态。
|
Waiting(
无限
等待
)
|
一个线程在等待另一个线程执行一个(唤醒)动作时,该线程进入
Waiting
状态。进入这个状态后是不能自动唤醒的,必须等待另一个线程调用notify
或者
notifyAll
方法才能够唤醒。
|
Timed
Waiting(
计时
等待
)
|
同
waiting
状态,有几个方法有超时参数,调用他们将进入
Timed Waiting
状态。这一状态将一直保持到超时期满或者接收到唤醒通知。带有超时参数的常用方法有Thread.sleep
、
Object.wait
。
|
Teminated(
被
终止
)
|
因为run
方法正常退出而死亡,或者因为没有捕获的异常终止了
run
方法而死亡。
|
8、线程池
- 创建线程池对象。
- 创建Runnable接口子类对象。
- 提交Runnable接口子类对象。
- 关闭线程池
public class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("实现线程");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程实现: " + Thread.currentThread().getName());
}
}
//测试类
public class ThreadPoolDemo {
public static void main(String[] args) {
// 创建线程池对象
ExecutorService service = Executors.newFixedThreadPool(2);//包含2个线程对象
// 创建Runnable实例对象
MyRunnable r = new MyRunnable();
//自己创建线程对象的方式
// Thread t = new Thread(r);
// t.start(); ‐‐‐> 调用MyRunnable中的run()
// 从线程池中获取线程对象,然后调用MyRunnable中的run()
service.submit(r);
// 再获取个线程对象,调用MyRunnable中的run()
service.submit(r);
service.submit(r);
// 注意:submit方法调用结束后,程序并不终止,是因为线程池控制了线程的关闭。
// 将使用完的线程又归还到了线程池中
// 关闭线程池
//service.shutdown();
}
}
9、IO分类
- 输入流 :把数据从 其他设备 上读取到 内存 中的流。
- 输出流 :把数据从 内存 中写出到 其他设备 上的流。
- 字节流 :以字节为单位,读写数据的流。
- 字符流 :以字符为单位,读写数据的流。
10、字节流与字符流
-
java.io.InputStream 字节输入流
-
java.io.OutStream 字节输出流
-
java.io.Reader 字符输入流
-
java.io.Writer 字符输出流
11、缓冲流的作用
在IO操作时,基本是读一次数据,再写一次数据,效率很慢。若使用缓冲流的话,内存读取的数据会暂时放在缓冲区,然后硬盘一次性读完,降低了读取次数,提高读取效率。