java基础笔记
1 static
- 类成员变量被静态修饰,该类的所有对象享有改成员变量同一块内存区
2 局部代码块
- 在方法内用{}包裹的代码
- 作用:限定生命周期
3 构造代码块
- 在类的成员位置,用{}包裹,在执行构造方法前会执行
- 作用:可以把多个构造方法中共同的代码放到一起,对 对象初始化
4 静态代码块
- 在类的成员位置,用{}包裹,用static修饰
- 作用:对类的初始化
5 继承关系下代码块运行流程
- 父静态代码块->子静态代码块->父构造代码块->父构造方法->子构造代码块->子构造方法
6 多态中
- 成员变量
编译看左边,运行看左边 - 多态中静态方法
编译看左边,运行看左边(静态和类相关,所以不算重写,访问还是左边) - 多态中成员方法
编译看左边,运行看右边
7 抽象类的构造方法
- 不能实例化,主要是给子类初始化父类数据用的
8 接口
成员变量是 默认加 public static fanil修饰的
成员方法默认 public abstract 修饰的
-
接口是无构造方法的
-
接口是可以多继承的
9 内部类调用对象
Outer.Inner oi=new Outer().new Inner();
-
如果内部类被静态修饰
Outer.Inner oi=new Outer.Inner();
-
外部类名限定this对象
Outer.this.num;
10 局部内部类
- 局部内部类中使用方法中局部变量的时候必须使用final 因为局部内部类是 引用类型,
方法中局部变量会随方法消失,而局部内部类的引用不会消失,因此将 局部变量用final修饰
时,编译后会自动变成常量,直接被使用,不会被回收
11 字符串
Stirng s1=new String("abc");和String s2="abc"的区别
- 前者会在堆内存中创建对象,再去方法区中的常量池找常量,没有则创建,s1引用堆内存对象指针,对内存对象指针引用
- 方法区常量池指针
- 后者直接在方法区常量池创建字符串,s2应用改方法区常量池中的字符串指针
- 如果是变量相加,则会先开空间,再拼接
- 如果是常量相加,则会先拼接,在去方法区中常量池里头找是否有此字符串,有则使用,无则创建
12 引用类型
-
参数传递时引用类型时,对引用类型用==赋值,会不起作用
-
原理:方法参数传递时,方法参数是真实对象的引用,并且指引真实的地址,当对方法参数的引用使用==赋值时,仅仅是修改方法内的参数的引用。对实际不起作用。
13 冒泡排序
- 从第 0个开始 相邻的 两两比较,如果前者比后者大,则交换位置。
14 选择排序
- 本人最长用,拿第一个默认为最小值,然后和所有元素比一遍,比当前最小值还小的就替换位置。
15 进制的范围
- 2-36 因为 0-9 a-z一共36个
16 Scanner
- System.in是一个系统的输入流
利用Scanner进行包装,可以快速将输入流中获取的数据通过api(eg: nextLine() nextInt()...)进行转型
17 正则表达式
[abc] 表示检测 是否是 a或b或c 一个字符 []里面的特殊符有五个:[]-\^,其他字符都是普通字符,包括*.?等。
[^abc] 表示检测 不能为 a或b或c 一个字符
[a-zA-Z]表示所有字母 一个字符
[0-9]表示数字 一个字符
. 代表任何字符 一个字符(不包括换行) 表示自身 用\.
\s 空格,tab,换行
\S 等价[^\s] 匹配任意字符[\s\S]
\d 代表[0-9] 使用的时候要转义 \\d
\D 代表[^0-9]
\w 代表[a-zA-Z_o-9] 所有单词
\W 代表[^\w] 非单词
^ 行开头 在[]内表示取反
$ 行结尾
\b 单词边界 非单词的地方就是单词边界
| 多个数据选一(常用于多字符)
http|ftp|svn abc 会获取到 http,ftp,svn abc
用(http|ftp|svn) abc 会获取到 http abc,ftp abc,svn abc
() 数据分界和取数据
例子 (a(b(c))) 则
\1(分组一)为 abc \2 为 bc \3 为 c
分组 表示对前面数据 分界的引用
$1 替换分组内的内容
(?:) 非捕获组
分组排除用此表示符的组
次数符
? 一次或一次都没有
* 零次或多次
+ 一次或多次
{n} 刚好n次
注意如果刚好需要匹配字符{1},则正则需要给{进行转义,得到\{1}的正则。
如果{}中间不是数字,则{}本身不需要转义。
{n,} 至少n次
{n,m} 至少n次,不超过m次
() 用于包括整体,后面跟着 次数符 可以限定小括号内的出现次数
eg:
[a-zA-Z_0-9]+@[a-zA-Z_0-9](\\.[a-zA-Z_0-9]{2,})+ 表示邮箱
\\w+@\\w(\\.\\w{2,})+ 邮箱高级版
String对象有 boolean matches(String regex)用于判断字符串是否匹配给定字符
String对象有 String[] split(String regex) 用于分割字符串
String对象有 String replaceAll(String regex,String replacement) 用于根据正则替换字符串
------------高级-----------
使用原则
定锚点(利用正则定位出需要使用正则的最小区域,一般确定锚点时都指定下末尾结束字符,提高效率)
eg:
获取<meta content="text/html; charset=utf-8" http-equiv="content-type">
锚点 meta 结束 >
charset 结束 "
<meta[^>]*?charset=([^"]+)"
利用 [^>]确定meta长度,利用[^"]确定长度
去噪点(去掉无关数据)
取数据(利用子模式来获取数据)
?表示非贪婪模式,默认为贪婪模式
区别
贪婪模式会越过之后条件,根据当前条件匹配所有字符串,之后挨个字符 回溯 进行判断是否匹配(从整个慢慢缩减匹配)
非贪婪模式 会根据当前条件挨个向下一个字符判断到不满足条件结束,进行之后条件的判断(从单个字符慢慢增量到整个匹配)
经常用
[^>]* 贪婪 代替 .*?> 非贪婪
使用时机
前面匹配千万不要同时能够适配到后面需要匹配的数据,使用注意按照字符串顺序来进行匹配(挨个或挨段匹配)
贪婪 通过 [^结束字符]* 这种限定的方式能快速匹配到完整的数据,不要再单独匹配这个完整的数据,最好是获取数据的时候用
非贪婪模式 [^结束字符]*? 通过这种限定方式会一个字符一个字符匹配满足条件的字符串知道匹配到结束字符,最好是过滤不需要的字符时候用
环视(断言/零宽断言)
环视主要有以下4个用法:
(?<=exp) 匹配前面是exp的数据
(?<!exp) 匹配前面不是exp的数据
(?=exp) 匹配后面是exp的数据
(?!exp) 匹配后面不是exp的数据
环视匹配可多次匹配,普通匹配不能
环视匹配不占宽度,环视匹配结果不纳入数据结果
18 正则匹配器
String="被匹配字符串";
String regex="匹配规则";
Pattern p=Pattern.compile(regex);
Matcher m=p.matcher(s);
Matcher实例
- matches 用于将整个输入序列与匹配规则匹配,看是否满足
-
lookingAt 阐释从区域开头开始的输入序列与匹配规则匹配 仅匹配开始区域
public boolean find();//此方法用于查找是否有匹配的字符串,调用第一次返回第一次满足,以此类推 利用public int start()获取满足字符串的起始位置,public int end()获取满足字符串末尾位置, public String group()获取满足字符串的子串
-
find 扫描输入序列以查找与该模式匹配的下一个子序列
public boolean find();//此方法用于查找是否有匹配的字符串,调用第一次返回第一次满足,以此类推 利用public int start()获取满足字符串的起始位置,public int end()获取满足字符串末尾位置, public String group()获取满足字符串的子串
19 Math
abs()绝对值
ceil()向上取整
floor()向下取整
max(a,b)取最大值
min(a,b)取最小值
pow(a,b) 取a的b次幂
random()取随机数 [0.0,1.0)
round()四舍五入
sqrt()返回正平方根
20 随机数
public int getRandom(int start,int end){
return (int)(Math.random()*(end-start+1))+start;
}
21 Random
构造分为有种子和没种子的
- 有种子的,每次获取的随机数值是一样的
- 没种子的,是默认当前时间毫秒值来当种子
22 System
包含一些有用的类字段和方法,该不能被实例化
gc()运行垃圾回收器,该方法调用后会启用垃圾回收器,寻找当前内存中可被回收的内存,并且
调用被释放内存的finalize方法,释放内存。
exit(int state)终止当前正在运行的虚拟机 exit(0),0表示正常终止
currentTimeMillis()返回当前时间与协调世界时1970年1月1日午夜之间的时间差(以毫秒为单位)
arraycopy(object src,int srcPos,Object dest,int desPos,int lenth)复制数组
23 BigInteger
- 用于对大于普通int值得数字做操作运算
24 BigDecimal
- 用于解决float,double精度丢失问题
25 SimpleDateFormat
SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
String=format(Data)格式化Data
Data=parse(String)解析格式化后的内容
26 Calendar
日历抽象类
Calendar.getInstance()获取实例
get(Calendar.常量)获取年月日等日期值
add(Calendar.常量,值)给日历指定对应时间
set(int year,int month,int date)设置日历当前时间
27 集合
- List
特有方法
void add(int index,Object element)在指定位置添加元素 注意:只能在size大小内添加,否则越界异常
ListIterator listIterator()返回List集合特有的迭代器
特有功能:
逆向遍历,可以通过previous()配合hasPrevious()返回上一个元素
add()增加功能,在迭代的时候增加元素(解决问题:迭代器遍历时,利用list直接add,会造成并发修改异常,因为迭代器是根据当前List大小做迭代,list大小变化后,没有及时通知迭代器)
Object set(int index,Object element)根据索引修改元素,返回被修饰的元素
subList(int fromIndex,int Index) 返回集合[fromIndex,Index)的部分
- ArrayList
底层是数组,查询快,增删慢,线程不安全,效率高
- Vector
底层是数组,查询快,增删慢,线程安全,效率低
特有方法:此类为jdk早期类,所以方法名还没有被规范
void addElement(Object obj) 增加元素类似普通List的add
Object elementAt(int index)获取索引指向的元素
Enumeration elements()获取迭代器
- LinkedList
底层是链表,查询慢,增删快,线程不安全,效率高
特有方法:
void addFirst(Object e)在首位增加一个元素
void addLast(Object e)在末尾增加一个元素
Object getFirst()获取首个元素
Object getLast()获取末尾元素
Object removeFirst()移除首位元素并返回被移除的元素
Object removeLast()移除末尾元素并返回被移除的元素
28 泛型
- 泛型类 public class 类名<T>{}
问题:
有些类保存很多实现时才能确定类型的对象,如果写多个类不利于维护,代码冗余
且成本高,用Object容易出现转型以及安全性问题。
解决方案:
jdk5引入泛型,将此类型的类中管理的对象类型,由实例时才确定使用类型。
- 泛型方法 public <T> void 方法名(T t){}
问题:
某些方法返回值或参数需要有多个重载,且方法体内代码一样,造成方法冗余。解决方案:
引入泛型方法,方法中参数以及返回值最终确定是由调用时决定
- 泛型接口
public interface 接口名<T>{}
public class 类名<Timplements 接口名<T>{}
问题:
接口是泛型,但是创建的类还是无法确定继承接口的方法需要使用的类型
需要实例使用时确定
解决方案:
创建的类也必须引入泛型类
- 泛型通配符
这个东西是和T不同, T是在定义类考虑到使用时才能确定类型时才使用T
? 表示通配符 ,是在使用时,限定实例泛型用的
注意,使用?后改引用就不能正常赋值了,赋值只能赋值null,但是可以获取 ? 限定实例的泛型 可以是任意类
eg:
Collection<?> c =new ArrayList<Object>();//自身也行
问题:
使用泛型时,左边泛型使用父类,右边泛型使用子类报错
解决方案:
原因,泛型使用时左右必须一致,不一致会报错,引入 ? 表示通配任何类
? extends E 向下限定
限定实例的泛型必须是 引用的泛型的 子类或本身
eg:
Collection<? extends Animal> c =new ArrayList<Animal>();//自身也行
Collection<? extends Animal> c =new ArrayList<Dog>();
问题:
当使用?作为泛型时赋值实例可以填写任意的类。造成不安全的问题
解决方案:
为了使用实例时明确实例类型,使用<? extends 实例使用的泛型的父类>,就
可以限定实例泛型的类型必须继承 实例使用的泛型的父类
? super E 向上限定
eg:
Collection<? super Animal> c =new ArrayList<Animal>();//自身也行
Collection<? super Animal> c =new ArrayList<Object>();
限定实例的泛型必须是 引用的泛型的 父类或本身
29 增强for 底层是迭代器
30 静态导入
import static 包名.类名.方法(方法必须是静态)
使用就可以直接用方法了
31 可变参数 jdk5 出现
public static int sum(int... a){//底层a其实是个数组,并且可变参数必须在最后一个
//用增强for可以获取每个参数
}
eg:
Arrys中有
public static <T> List<T> asList(T... a)
注意:
将数组转换成List后,集合长度是固定的, 如果修改集合长度(例如增加或删除元素)
会抛出UnsupportedOperationException异常
修改元素不改变集合长度则可正常。
32 Set
存取顺序和取出顺序不一致,唯一 注意,因为获取顺序不一致,所以
没有通过索引获取值得方法。只能通过 迭代器,增强for的方式来获取值)
-
HashSet
底层是HashMap,将元素当成key保存,value为相同的object,来保证唯一性
(HashMap底层是有个Hash表(Tip:Hash表的结构是元素为链表的数组,被存入对象
Hash值不同的情况下,会根据Hash值的不同,存进数组,Hash相同的情况下,
会调用被存入对象equals方法和已存入Hash表中此Hash值的链表中其他元素判断,不同则存进数组Hash相同的链表中),
把要存的key都经过hash转换后比对,如果hash值相同则不保存
如果相同则再进行 地址 以及 equals方法对比) -
LinkedHashSet
底层数据结构由哈希表和链表组成
- 哈希表保证元素唯一性
- 链表保证元素有序
-
TreeSet
- 底层是二叉树(红黑树是一种自平衡的二叉树)
- 能够对元素按照某种规则进行排序
- 自然排序
- 无参构造使用自然排序
- 实现Comparable才能自然排序
- 比较器排序
- 带参构造使用比较器排序 参数类型为Comparator
33 Map
- HashMap
- keySet获取键集合
- values获取值集合
- entrySet获取键值对集合
小tip :0开头是八进制只有0-7
-
LinkedHashMap
- 哈希+链表 保证唯一有序(存入和取出顺序一致)
-
TreeMap
- 基于红黑树
- 对元素排序
34 Collectons
- 集合操作类
- sort(List) 对参数默认自然排序
- binarySearch(List,key) 二分查找某个key的Index
- max(Collection) 最大值
- reverse(List) 反转 (排序反转)
- shuffle(List) 随机置换 (随机换位置)
35 集合类总结
- List存储取出有序可重复
- Hash不可重复
- Linked 存储取出有序 增删快,查询慢
- Map 键值对
- Tree 储存内容按照规则排序
- Set 储存取出 无序 唯一
36 异常
- jdk7 新特性
处理同类型异常,注意:catch的异常类型必须是平级,不允许出现父类
try{
...
}catch(异常类型 | 异常类型 | 异常类型 ... 变量名){
...
}
- 编译时期异常 必须处理否则编译不通过,使用try catch做处理才能正常运行
- 运行时期异常 不抛出也不会出错
- 编译时异常 面相开发者,希望被调用的时候处理用这个
- 运行时异常 面相程序,虚拟机运行出错时调用
catch中出现return 会 经过finally后return,但是return的值一般会直接先定好
子类继承父类,父类方法有抛异常,子类也必须抛相同或者父类异常的子类
37 File
File(String pathname)根据路径返回一个File对象 不写盘符,默认路径在当前项目
File(String pathname,String child)根据路径,和子文件名返回一个File对象
File(File parent,String child)
createNewFile()创建文件
mkdir()创建文件夹
注意 :创建文件或文件夹的目录必须存在
mkdirs()
创建文件或文件夹的目录不存在则创建
delete()删除文件或文件夹
注意:删除目录时,必须无子
rename(File) 重命名
isDirector() 是否是目录
isFile()是否是文件
exists()是否存在
canRead()能否读取
canWrite()能否写入
isHidden()是否隐藏
getAbsolutePath() 获取绝对路径
getPath() 获取相对路径
getName() 获取名称
length() 获取字节数
lastMoaified() 获取最后修改时间,毫秒值
list() 获取指定目录下的所有文件或者文件夹的名称数组
listFiles()获取指定目录下所有文件或文件夹的File数组
list(FilenameFilter filter) 使用文件过滤器,过滤成功才会放入返回值
listFiles(FilenameFilter filter)
38 IO流
-
字节流
- 输入 InputStream
- 输出 OutputStream
-
字符流
输入 Reader结尾的
输出 Writer结尾的
tip: 字符占2个字节,不close时必须flush刷新缓冲区才会写入磁盘,字节占一个,直接可写入
OutputStreamWriter = OutputStream + 编码表
InputStreamReader =InputStream + 编码表
tip:OutputStreamWriter和InputStreamReader属于一个转换器,将字节流加上编码转换成字符流
FileReader 对InputStreamReader进行封装
FileWriter 对OutputStreamWriter进行封装
tip:计算机中,中文字符保存是由两个字节保存,计算机是如何识别 字节数组中那些需要拼成中文,那些不需要呢?
原因,中文字符两个字节一般第一个字节都是负数,如果是复数,计算机自动将当前以及后一位进行拼接
-
字节缓冲区流
- 输入 BufferInputStream
- 输出 BufferOutputStream
-
字符缓冲流
- BufferReader
- BufferWriter
-
数据流 专门操作基本数据类型
- DataInputStream
- DataOutputStream
-
内存操作流
-
操作字节数组
ByteArrayIntputStream ByteArrayOutputStream
-
操作字符数组
CharArrayReader CharArryWriter
-
操作字符串
StringReader StringWriter
-
-
打印流
PrintStream PrintWriter
tip:只能操作目的地,不能操作数据源(没有输入流,只有输入).
-
随机访问流
RandomAccessFileDemo
** tip:可设置读取位置,获取当前位置**
-
合并流
SequenceInputStream
将多个流合并成一个流
-
序列化流
ObjectOutputStream
-
反序列化流
ObjectInputStream
tip:将对象进行读取以及写入,被序列化的类必须继承Serializable标记接口
序列化接口存在一个标记值,这个标记值会在序列化后保存与序列化中, 如果要获取的话
必须有相同标记值的类才能被正常的反序列化
标记值 serialVersionUID
不想被序列化字段声明 transient
-
属性工具
Properties读取本地键值对文件
-
Jdk7新特性
- NIO新的IO操作
- Path:路径
- Paths:有一个静态方法返回一个路径
public static Path get(URI uri)
- Files:提供了静态方法供我们使用
public static long copy(Path source,OutputStream out):复制文件
public static Path write(Path path,Iterable<? extends CharSequence> lines,Charset cs,OpenOption... options)
线程
- 线程名 Name
- 线程优先级 Priority
默认优先级5
- 休眠 sleep()
- 加入线程 join()
让自身线程执行完毕,之后的线程才能继续
- 礼让线程 yield()
- 后台线程(守护线程,用户线程)Deamon
如果主线程死亡后,其余线程都是守护线程则会自动结束守护线程
- 停止线程stop() 过时
- 中断线程 interrupt() 利用线程抛出异常来进行中断
- 同步代码块 synchronized(对象){}
对象: 多个线程使用的同个对象
- 同步方法
- 锁
- 非静态 this
- 静态是 类的字节码文件对象
**tip:Collections.synchronizedXXX() 此方法是将非线程安全的集合转换为线程安全的集合**
- Lock
- look()加锁
- unlook()解锁
- 等待唤醒机制
- Object中(锁对象)
wait()等待,后会立即释放锁
notify()唤醒单个线程
notifyAll()唤醒所有线程
- 线程组
ThreadGroup 默认都为为main线程组
- 线程池
- Executors
ExecutorService newFixedThreadPool(int n) 创建一个带有n个线程的线程池
- ExecutorService
submit() 参数可以可执行Runnable或Callable对象
shutDown() 结束线程池
定时器
Timer 定时
TimerTask 任务
网络编程
-
通讯协议
- UDP 速度快,不安全
- TCP 速度慢,安全
-
Socket
封装了IP,端口
-
UDP:
DatagramSocket 发送和接收 DatagramPackage 发送包
-
TCP:
- Socket 客户端
getOutPutStream()获取输出流进行数据输出
- ServerSocket 服务器端
accept()获取Socket对象,监听客户端连接,此方法会阻塞等待客户端连接
Socket.getInputStream()获取输入流
反射
-
Class文件对象
-
获取方法
Object.getClass(); 类.Class; Class.forName("包名.类名");
-
Constructor对象获取方法
getConstructors();此方法只能获取所有公共(public)构造方法 getDeclaredConstructors();获取所有构造方法 getConstructor(Class... parameterType);参数为需要获取的方法的签名,返回公共匹配的构造方法 getDeclaredConstructor(Class... parameterType);参数为需要获取的方法的签名,返回所有匹配的构造方法
-
Constructor使用
newInstance(Object... initargs);创建对象,参数为初始化要用到的参数
上面这个方法如果访问private会报非法访问异常,解决方案setAccessible(true);设置取消java访问检查
-
- Field成员变量获取方法
getFields()获取所有public成员变量
getDeclaredFields()获取所有成员变量
getField("成员变量名")获取指定public成员变量
getDeclaredField("成员变量名")获取指定任意成员变量
- Field使用
set(Object obj,Object value)给指定对象的Fielda赋值
> 上面这个方法如果访问private会报非法访问异常解决方案setAccessible(true);设置取消java访问检查
- Method成员方法获取方法
getMethods()获取所有public的method方法(获取所有包括父亲的)
getDeclaredMethods()获取所有method(仅获不包括父亲的)
getMethod("方法名",Class... parameterType)获取指定public方法名的method
getDeclaredMethod("方法名",Class... parameterType)获取指定方法名的method
- Method使用
invoke(Object obj,Object..args)
> 上面这个方法如果访问private会报非法访问异常,解决方案setAccessible(true);设置取消java访问检查