JAVA高级笔记
- 工具类
- Object类
它是所有类默认继承的父类,在Object类中定义的方法,所有的类都默认继承。
equals方法:判断两个对象是否“相等”
Object中equals方法相当于“==”,比较的是内存地址
A instanceof B
变量(对象)A是否是类(Class)B的实例
True A是B的一个对象
False A对象的类型不是B
通过重写equals方法完成自己判断是否相等的逻辑
toString方法:将对象的内容,组成String类型返回
当直接输出某个对象时,默认输出的是toString()方法的内容
----------------------------------
练习: 创建一个Emp类 int empno 员工号, String ename
两个Emp对象的员工号一致认为两个对象“相等”
Sysout(e) 显示的不是内存地址,而是员工编号和姓名
hashcode方法
hashcode与内存有关
特征:
- 同一个对象多次调用hashcode方法得到的数值应该始终不变
- 如果两个对象==的结果是true,那么它们的hashcode码应该也是一致的
- 如果两个对象的hashcode一致,不能证明它们是同一块内存
finalize方法
进行垃圾回收方法
Java的垃圾回收机制:低级线程不断扫描内存
笔试题:final,finally和finalize的区别
Final最终关键字,修饰类,方法和属性
Finally异常处理最终关键字,无论如何都会执行finally中的代码
Finalize垃圾回收的一个方法名
- 字符串类
- String:字符串常量类
String的API
- char c = str. charAt(int index); 返回对应位置的字符
- str1.equals(str2); 判断两个字符串的内容是否一致
- str1.equalsIgnoreCase(str2); 判断两个字符串的内容是否一致,忽略大小写
- int n = str.indexOf(str1); 在str中查找str1第一次出现的位置
- int l = str.lastIndexOf(str1); 在str中查找str1最后一次出现的位置
- str.isEmpty(); 判断str是否为空字符串(空字符串不是null),空字符串的表示形式””
- str.length(); 字符串的字符个数
- str.replaceAll(str1,str2);在str中使用str2替换所有的str1
- String[] s = str.split(“,”); 将str以“,”作为分割,拆分成一个字符串数组
- str.substring(); 截取字符串
- str. toCharArray(); 将字符串中的所有内容变成字符数组
- str.trim(); 去掉字符串两端多余的空格
练习:
在控制台上输入一个email地址,通过String的API判断该email地址是否合法
合法规则:
- 首字母不能为数字
- 必须有且仅有一个@和有且仅有一个.
- @不能是第一个字符,.不能是最后一个字符
- @和.之间必须有其他内容
- StringBuffer:字符串变量类,线程安全,效率低
大量的字符串拼接操作时,StringBuffer的效率优势要远远高于String。工作中一定要使用StringBuffer进行字符串拼接
- StringBuilder:字符串变量类,线程不安全,效率高
速度比StringBuffer还要快
字符串类型的笔面试题
- String str1 = “abc”;
String str2 = “abc”;
String str3 = new String(“abc”);
Str1 == str2 ? true
Str1 == str3 ? false 比较内存地址
Equals方法比较的内容
- String,StringBuffer和StringBuilder的区别?
String是字符串常量,拼接效率低
StringBuffer是字符串变量,线程安全,拼接效率比String高
StringBuilder是字符串变量,线程不安全,拼接效率比StringBuffer还高
- 日期时间类
- java.util.Date类(默认)
构造方法
- new Date(); 得到当前时间
- new Date(long l); 根据毫秒数得到时间
API方法
- before和after
- compareTo
- equals
- getTime和setTime
- java.sql.Date类
是与数据库中Date类型进行数据交互的类,它是java.util.Date的子类
构造
new Date(long l); //根据毫秒数进行构造
API
setTime 与父类用法一致
- SimpleDateFormat类(重要)
字符串和日期之间的互相转换的类
构造方法
New SimpleDateFormat(“fmt”)
API方法
String str = sdf.format(Date d); //将date按照fmt声明的格式转换成对应格式的字符串
Date d = sdf.parse(String str); //将字符串表示的日期,以声明的fmt格式方式解析成Date对象
(str必须符合fmt格式的要求,如果不符合会报出异常)
- Calendar类 日历类
API
get(int field);取得对应字段的值
set(int filed, int value); 为对应字段设置值
getTime(); 返回与日历表示时间相同时间一个date对象
setTime(Date d); 使用d对象设置日历时间
getTimeInMillis(); 得到日历时间的毫秒数
setTimeInMillis(long l); 使用毫秒数设置日历时间
用途:设置某个程序的自动启动时间
- java.sql.Timestamp类
- Math类
Math类不能创建对象,构造方法私有。
所有的属性和方法都是静态的
API
ceil(double a) :获得比a大的最小整数(进一法)
floor(double a) : 获得比a小的最大整数(舍弃小数)
round(double a): 四舍五入
pow(double a, double b): 计算a的b次幂
sqrt(double a) :取得a的正平方根(对a开平方)
cbrt(double a) :取得a的正立方根(对a开立方)
random() : 取得[0,1)区间的随机浮点数
- System类和Properties类
System.out 对象
System.out.println() 控制台打印方法
System.exit(0); 0:正常退出虚拟机 -1:表示异常退出
System.gc(); 立刻调用垃圾回收
System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
参数:
src: 被拷贝的源数组
srcPos: 源的位置
dest: 拷贝到目标数组
destPos: 目标位置
length: 拷贝长度
java.util.Properties类
是一种键值对性质的内容
Properties p = System.getProperties(); //获取系统信息的集合
String value = p.getProperty(“key”)
Key值可以写下图的内容
- 包装类
基本数据类型的包装类:8种
包装类的主要作用:基本数据类型在引用数据类型上的投射。
包装类是引用数据类型,体现的是基本数据类型。在某些场合下,只能使用引用数据类型(比如:泛型),这个时候需要使用包装类。
byte |
java.lang.Byte |
short |
java.lang.Short |
int |
java.lang.Integer |
long |
java.lang.Long |
float |
java.lang.Float |
double |
java.lang.Double |
char |
java.lang.Character |
boolean |
java.lang.Boolean |
所有数字(整数和浮点数)类型的父类java.lang.Number
JDK1.5版本开始,Java中引入了自动装箱和自动拆箱
JDK1.5之前,我们无法通过直接将一个值赋值给包装类
Integer i = new Integer(5); // JDK1.5之前的标准做法
Integer j = 5; //自动装箱 (5还是保存在堆里)
int k = i.intValue(); //JDK1.5之前的标准做法
int m = j; //自动拆箱 (将堆中的5赋值给m)
API
以Integer为例
Int i = Integer.parseInt(“12”); //将字符串转换成int类型
如果字符串中不是整数,会抛出java.lang.NumberFormatException
- 集合类(非常重要)
集合是一些事物组成的整体,集合中允许出现不同类型的数据。
集合是不定长的,随着内容数量改变,其自身的长度随着变化。
学了集合之后,基本上就使用集合来完成数组的一些操作。
- Collection接口(线性集合)
- List接口(十分重要:有序号可重复)
- ArrayList实现类(十分重要)(线程不安全)
size(): 获得集合中的内容个数,所谓的集合长度
add(Object o):向集合的结尾添加一个数据o
add(int idx, Object o): 向idx位置中插入一个数据o
remove(Object o): 移除集合中的第一次出现对象o
remove(int idx) : 移除idx位置上的元素,后面元素自动向前移动,(如果Object是int类型,优先按照下标移除)
set(int idx, Object o): 将idx位置上的元素替换为o
Object o = get(int idx): 得到idx位置的元素,但不移除它
ArrayList的底层实现是基于数组实现的
--------------------------------------------------------------
练习:使用Arraylist实现类完成下述内容
- 创建集合对象
- 向集合结尾随意添加5个数据
- 取得下标是2的数据
- 替换下标2位置的数据为“haha”
- 移除下标1位置的数据
- 在控制台上输入一个字符串,判断在集合中是否存在
- LinkedList实现类(十分重要)
底层是基于双向链表实现的
面试/笔试:数组与链表的区别(十分重要)
数组在内存中是连续的空间,查找效率高,插入删除效率低。
链表在内存中是分散的空间,查找效率低,插入删除效率高。
面试/笔试:ArrayList与LinkedList的区别?
ArrayList基于数组实现,LinkedList基于链表实现
阐述数组与链表的区别即可。
面试:根据实际情况,一组数组经常需要查找,很少改动,用哪种集合? ArrayList
- Vector实现类(线程安全的ArrayList)
ArrayList和Vector的区别,线程不安全与线程安全。
------------------------------------------------
作业:控制台学生系统, 将数组改写成集合实现
- Set接口(无序号不重复,用迭代器访问)
- HashSet实现类
- TreeSet实现类
HashSet底层基于Hash表的算法,TreeSet底层基于二叉树的算法。
用途:去重复(前提:顺序可以打乱)
笔试/面试:List接口与Set接口的区别?
List:有序可重复,可以使用下标访问,存放顺序可控
Set:无序不重复,只能用迭代器访问,存放顺序不可控
- Map接口(键值对集合 key-value)
一个位置上存储一个键(key)值(value)对,键值是不能重复的,值是可以重复的。如果设置了相同的key,后存入的会覆盖先存的。Map接口无法通过下标访问,遍历只能通过迭代器访问。
- HashMap和HashTable实现类(键值是靠hash算法实现的)
HashMap是线程不安全,效率高,key值允许为null
HashTable是线程安全,效率低,key值不允许null
API
clear(); 清空Map集合中的所有的键值对
isEmpty(); 判断集合是否为空
containsKey(Object o); 判断key中是否存在o
containsValue(Object o); 判断value中是否存在o
entrySet(); 返回键值对组成的Set集合
keySet(); 返回key组成的Set集合
get(Object key); 根据key值返回对应的value
put(Object key, Object value); 向集合中存放key-value键值对,如果key已存在,使用value替换原有的值。
remove(Object key) 移除key对应的key-value键值对
remove(Object key, Object value) 根据key-value进行移除
size() 返回集合中键值对的个数
- TreeMap实现类(键值时靠二叉树算法实现的)
作业:将学生控制台系统中的集合改写为使用Map集合实现
Key是学号 value是student对象
- 泛型
类型参数化
用途:约束集合内容的类型
- 文件类和流(Stream)类 java.io包
IO: input和output
- File类 – 文件类(文件和文件夹)
表示的是系统中文件自身的属性和行为,不包括文件的内容。
构造方法:
File(File parent, String child)
表示在parent表示的文件夹下的child文件
Parent: c://Programe Files/haha (File类型)
Child: 1.jpg
路径:c://Programe Files/haha/1.jpg
File(String parent, String child)
Parent: c://Programe Files/haha (String类型)
Child: 1.jpg
路径:c://Programe Files/haha/1.jpg
表示pathname路径所示的文件
pathname:c://Programe Files/haha/1.jpg
文件类不会默认去创建文件
File类的API
createNewFile() 创建文件,不能创建文件夹
mkdir() 创建文件夹
mkdirs() 创建完整文件夹路径 推荐使用
注意区分:创建文件夹使用mkdirs,创建文件使用createNewFile
练习:在D盘创建文件夹a,在a中创建1.jpg文件
在a中创建b/c/d路径,在d文件夹下创建2.jpg文件
delete() 删除文件或空的文件夹。
exists() 判断目录或文件是否存在
获取文件名和父级目录的方法
getName() 得到文件名
getParent() 得到文件所在文件夹的路径
getParentFile() 得到文件所在文件夹的路径的file对象
获取路径的三个方法
getAbsolutePath()
getPath()
getCanonicalPath()
判断文件对象的状态
canRead() 是否可读
canWrite() 是否可写
canExecute() 是否可执行?
isDirectory() 判断文件对象是否是目录(文件夹)
isFile() 判断文件对象是否是文件
isHidden() 判断文件对象是否为隐藏
length() 文件的大小
硬盘上“簇”的概念:硬盘上存储内容的最小单位,文件占用的空间一定是簇的倍数。Length获得的是文件的实际大小不是占用空间大小。
获取子目录和子文件
list() 获得目录的子目录和子文件的字符串数组
listFiles() 获得目录的子目录和子文件的文件数组
练习:在控制台上模拟CMD指令
dir: 查询当前目录下的子目录和子文件
显示文件名,大小,是否是文件夹,是否隐藏
cd abc: 进入到当前目录的子目录abc中
cd.. : 返回上级目录
create file xxx: 在当前目录中创建名字是xxx的文件
exit : 结束程序
- 流(Stream)类 操作流载体(文件是其中之一)的内容
流在不同的介质中进行流动传递数据的事物
介质:内存,硬盘,网线,无线网络…
- 字节流和字符流
流的单位:
字节1Byte
可以处理任何文件,用于传输二进制数据(图片,音频…)
字符 2Byte
可以处理txt文件,用于传输文本内容
- 输入流和输出流
流的流向
输入: 从其他介质进入内存(程序)
输出:从内存(程序)进入其他介质
- 原始流和处理流
流的功能
原始:提供基础功能的流
处理:提升效率,提供额外功能
流的四个基类(后缀)
|
输入 |
输出 |
字节 |
InputStream |
OutputStream |
字符 |
Reader |
Writer |
处理流: 以上述四个类名为后缀的基本都是处理流
File前缀: 关于文件
FileOutputStream: 向文件进行输出的流
FileInputStream:来自文件进行输入的流
FileReader和FileWriter 作用同理
Object前缀:关于序列化
序列化 ObjectInputStream和ObjectOutputStream
将二进制程序数据暂存,比如,将某个对象暂时保存在硬盘的文件上
能被序列化的类必须实现java.io.Serializable接口,同时生成类的序列化ID
类的属性需要序列化,也得实现java.io.Serializable接口
集合类大部分都实现了序列化接口
如果序列化类中某个属性不想参与序列化
transient:被该关键字修饰的属性,不参与序列化和反序列化
Buffered前缀:关于缓冲
缓冲,提升效率
BufferedInputStream和BufferedOutputStream
BufferedReader和BufferedWriter
\t Tab 制表符
\n 换行 新起一行
\r 回车 光标至行首
Print前缀: 网络传递数据
PrintReader和PrintWriter
使用处理输出流,需要进行flush。流在使用完毕后一定要关闭
-------------------------------------------------------------------------
作业1:完成一个文件的“剪切”操作 (复制后删除源文件)
练习2:将控制台学生管理系统中Map集合利用序列化保存数据
- 程序启动时,反序列化读取生成Map集合
- 程序通过5-退出时,将当前Map集合序列化保存至文件中
- 多线程
进程:软件在操作中体现为进程
线程:一个进程中的多个“同时”运行的程序
- 线程的实现方式
单核CPU:同一个时间点只能为一个进程中的一个线程服务
轮转时间片:所有程序在争抢CPU的执行权,一小段时间被称为“时间片”,时间片的时间非常短,所以看起来所有的程序都是同时运行的。
面试题/笔试题
Java中多线程的实现方式
- 实现Runnable接口,并重写其中的run方法
- 继承Thread类,并重写其中的run方法
推荐使用(1)种:把父类位置留出来,以防万一
多线程启动的方式
- Runnable接口,需要通过Thread对象进行加载,加载后通过Thread对象的start方法进行启动,启动后线程会以多线程的方式自动执行run方法中的代码
- Thread类方式,直接通过start方法启动即可
强调:通过run方法执行程序,相当于顺序执行,不是多线程。
Java.lang包是不需要引包即可使用的类
- 线程的生命周期
- 同步与异步 – 锁
Synchronized :同步 锁
当多个线程同时访问了一个“共享资源”时,由于线程run方法中代码执行不完整,造成数据错误,这种问题就是线程不安全。
解决线程不安全的办法是为资源加锁,推荐使用同步块的方式进行加锁
synchronized(共享资源){
操作共享资源的代码
}
除了同步块的方式,也可以使用同步方法(synchronized)进行处理,不推荐此种方式,这种方式加锁不灵活。
-----------------------------------------------------
选做:写一个程序模拟火车站售票窗口
共享资源 车票:20张
窗口:A,B,C三个窗口
Sell()方法进行售票,保证售票的行为是正确的
- 套接字(Socket)基于TCP/IP协议
网络连接:实现Java分布式特点 c/s结构
TCP/IP协议:基于IP地址作为计算机在网络上的“门牌号”,在不同的计算机之间进行通信。
特点:请求-响应方式 请求与响应是成对出现的。在第一次请求的响应没有到达时,不能发起第二次请求
客户端-服务器端联系是紧密的,客户端能够知道请求是否成功了
UDP协议:单向的广播。发送者不关心接收者是否收到消息。UDP的传输方式是不可靠。
面试题/笔试题:TCP与UDP的区别?
- ServerSocket类(服务器类)
- Socket类(客户端类)
Host: 计算机名,IP地址
如果是本机:127.0.0.1 localhost
练习:将猜数字游戏改为服务器生成,客户端猜测
- GUI – Java绘制图形界面 C/S结构
JFrame类:窗体类
JPanel类:面板类
内容在面板上,面板在窗体中。
JScrollPanel类:带有滚动条的面板类
JTextFiled:文本框
JPasswordFiled:密码框
JComboBox:下拉列表
JTextArea:文本区域
JLabel:固定文本
JButton:按钮
------------------------------------------------