一、其他
1、枚举
1)反编译
javap -c cn.edu.again.cs.Test1
2)枚举类中第一行必须定义常量,后续对常量进行封装
2.数据结构
1)栈:先进后出,后进先出
2)队列:先进先出,后进后出
3)数组
I)连续存储
II)查询快,增删慢
4)链表
I)游离存储,每个元素节点包含数据值和下一个元素的地址
II)查询慢,增删相对快
III)分类
i)单向链表
节点类 Node
数据 Object data;
指针 Node next;
链表类
头结点 Node head;
Node node = new Node();
node.data = data;
//头结点如果为空的话,先给头结点赋值并返回
if(head == null) {
head = node;
return;
}
add(Object data)方法
//将指针放到头结点位置
Node temp = head;
//如果指针所指向的位置不为空,指针右移
while(temp.next != null) {
temp = temp.next;
}
//为空的时候赋值
temp.next = node;
测试类
MyList list = new MyList();
list.add(12);
list.add(13);
list.add(14);
ii)双向链表:比起单向链表,双向链表多了一个前移的指针
5)树
I)只有一个根节点
II)二叉树(二叉查找树)-- 平衡二叉树 -- 红黑树
6)图
7)散列表
8)堆
3、泛型<>
1)通配符
? 通配
extends Animal 通配符上限 允许其和子类访问
super 通配符下限 允许其和其父类访问
2)定义位置
类上
方法上
3)使用
List< ? > t
List< ? extends Animal > t
List< ? super Pig > t
4、可变参数
1)一个方法只能有一个可变参数,并且放在最后,可变参数底层是一个数组
2)(int ... i)
5、异常
try {
int t = 10/0;
} catch(Exception e) {
//打印栈轨迹
e.printStackTrace();
}finaly{
}
1)对于异常,有三种处理方式
I)直接抛出,如果出现异常,虚拟机崩掉
II)直接处理,如果出现异常,直接try catch
III)暂时抛出,集中处理
二、基础类库
1、main
1)java程序入口
configuration 配置
arguments 参数
2)可以在args[] 数组中添加内容,通过args数组进行调用
2、System
1)System.currentTimeMills(); 1970年1月1日到如今的时间毫秒值
2)System.gc(); garbage collector申请垃圾回收
3)props.getProperty("java.vm.version"); 通过键获取值
//数组的拷贝
int[] arrs1 = {11,22,33,44,55,66,77,88};
int[] arrs2 = new int[5];
// 被拷贝数组,被拷贝起始索引,拷贝数组,拷贝起始索引,拷贝个数
System.arraycopy(arrs1,2,arrs2,1,3);
System.out.println(Arrays.toString(arrs1));
System.out.println(Arrays.toString(arrs2));
3、克隆 注意:克隆是内容一样地址不同
1)实现Cloneable接口
2)重写父类的clone()方法
I)对于重写方法的访问权限,必须大于等于原来的访问权限
II)子类重写父类方法的时候,返回值可以是父类返回值类型的字类
3)调用clone()方法
/**
* 克隆
* @author Again
*/
public class Test5 {
public static void main(String[] args) throws Exception {
Dog d1 = new Dog("nn",3);
Dog d2 =(Dog)d1.clone();
}
}
class Dog implements Cloneable {
String nameString;
int age;
/**
* 重写父类的clone()方法
*/
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone():
}
public Dog(String nameString, int age) {
super();
this.nameString = nameString;
this.age = age;
}
public Dog() {
super();
}
}
深克隆与浅克隆
1、(java)浅克隆:被Clone的对象的所有变量都含有原来对象相同的值,而引用变量还是原来对应的引用【拷贝对象时仅仅拷贝对象本身(包括对象中的基本变量)而不拷贝对象包含的引用指向的对象】
2、深克隆需要重写方法:被克隆对象的所有变量都含有原来对象相同的值,引用百年来那个也重新复制了一份【不仅拷贝对象本身,而且拷贝对象包含的引用指向的所有对象】
4、String
1)拓展:Spring和SpringBuffer都是CharSequencd的子类
2)增
String str = "dfadasg" | 新增 |
3)删
4)改
str.concat(String str); | 字符串的拼接,需要拿变量接,不会对原值进行更改 |
str.getBytes; | 字符串转字节数组 |
str.substring(3); | 从索引位置开始截取后半部分字符串 |
str.substring(3,5); | 截取开始索引到结束索引的字符串,包前不包后 |
str.toUpperCase(); | 字符串转大写 |
str.toLowerCase(); | 字符串转小写 |
str.toCharArray(); | 字符串转字符数组 |
str.trim(); | 去前后两头空格 |
byte[] bs = str.getBytes(); str = new String(bs); | 将字符数组转回字符串 |
byte[] bs = str.getBytes("gbk"); str = new String(bs,"gbk"); | 字符串的编码与解码 |
str = new String(bs,2,3); | 取byte数组bs的部分数据组成字符串,从索引2开始,取3个数据 |
String.valueOf(123); | int转String |
str.replace("l","a"); | 将l替换成a |
str.replaceAll("\\w+","a"); | 将连在一起的字符替换成a |
str.replaceFirst("l","a"); | 将第一个l替换成a |
str.split(","); | 以逗号分隔,返回字符串数组,如果最后一个字符是逗号,最后一个空不取,但如果逗号在中间,空取 |
str.split(",",index); | 以逗号分隔,返回字符串数组,返回个数为index,如果索引越界或者为负则按照最大长度计算,从前往后取分隔点 |
5)查
str.charAt("索引"); | 查找指定位置处的字符 |
str.compareTo(); | 比较哪个字符串靠前(字典)前大为正,后大为负,相等为0 |
str.contains("bn"); | 查看原字符串是否包含某子串 |
str.indexOf("j"); | 返回字符索引,不存在返回-1 |
str.indexOf("hf",5); | 从指定位置开始找,找到为止 |
str.lastIndexOf("hf"); | 从右往左找 |
str.startsWith("hf"); | 是否以"hf"开头 |
str.endsWith("dj"); | 字符串是否以"dj"为结尾 |
str.isEmpty(); | 判断字符串是否为空字符串 |
str.equals("ww"); | 判断是否相等 |
str.compareToIgnoreCase("HFjbdfs"); | 忽略大小写比较是否相等 |
6)用""直接定义出来的变量会直接放在字符串常量池中,即便用加号加在一起,也会在编译的时候合并到一处,用new新建出来的对象
5、字符串的拼接与修改
1)SpringBuffer:速度慢,安全性高
SpringBuffer sb = new SpringBuffer(); | 创建对象 |
sb.append("java"); | 直接拼接 |
sb.insert(3,"web"); | 在索引第三个位置插入 |
sb.toString(); | SpringBuffer类型转字符串类型 |
sb.delete(1,3); | 索引为1的位置开始删除,删除3个 |
2)SpringBuilder:速度快,安全性低
SpringBuilder sbd = new SpringBuilder(); | 创建对象 |
方法和SpringBuffer类似
6、Math
Math.abs(-5); | 绝对值 |
Math.ceil(3,5); | 向上取整 |
Math.floor(3.5) | 向下取整 |
Math.round(3.5); | 四舍五入取整 |
Math.random(); | [0,1)随机数 |
Math.pow(2,5); | 2的五次方 |
Math.sqrt(25); | 平方根 |
7、BigDecimal
1)处理:精度丢失问题
2)方法一创建对象
//加减乘除运算
BigDecimal a1 = new BigDecimal("0.1");
BigDecimal b1 = new BigDecimal("0.2");
//加法
System.out.println(a1.add(b1));
//减法
System.out.println(a1.subtract(b1));
//乘法
System.out.println(a1.multiply(b1));
//除法
System.out.println(a1.divide(b1));
//解决循环小数除不尽的问题
BigDecimal a2 = new BigDecimal("10");
BigDecimal b2 = new BigDecimal("3");
System.out.println(a2.divide(b2,2,BigDecimal.ROUND_HALF_UP));
注意:当使用方法的时候 new BigDecimal(); 括号里面写的是字符串类型,否则无意义,还是会造成精度丢失!!!
3)方法二使用接口
BigDecimal a3 = BigDecimal.valueOf(10);
BigDecimal b3 = BigDecimal.valueOf(3);
System.out.println(a3.divide(b3,2,BigDecimal.ROUND_HALF_UP));
三、日期与时间
1、System
System.currentTimeMillis(); | 计算时间毫秒值,从1970年1月1日到现在 |
2、Date 步骤
1)创建日期时间对象
Date d = new Date();
2)输出
I)输出系统时间
System.out.println(d);
II)输出系统时间毫秒值
System.out.println(d.getTime());
3)日期格式化
I)创建日期格式化对象
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
II)将时间对象化成格式化字符串
sdf1.format(d);
III)将字符串转化成时间对象
String str = "2000-11-11 11:11:11";
Date d2 = sdf1.parse(str);
3、Calendar
1)获取系统当前日历对象
Calendar c1 = Calendar.getInstance();
2)方法 注意月份是从0-11,真正的月份要+1
//获取年份
c1.get(Calendar,YEAR);
//向后三年
c1.add(CalendarYEAR,3);
//向前三年
c1.add(CalendarYEAR,-3);
3)对象的转换
//将日历对象Calendar转成Date对象
c1.getTime();
//将Date对象转为Calendar对象
c1.setTime(d1);
四、正则表达式
1、正则表达式
1)一种代码的简化方式
2)简化原则
1、()->{}
2、如果参数列表只有一个参数,那么小括号可以省略
3、如果{}内只有一行输出,那么{}可以省略
4、如果有返回值,那么省略{}的同时需要省略return关键字
5、并不是多有的匿名内部类都可以简化的
3)简化条件:必须是由@FunctionInterface修饰的接口
2、基本语法
1)字面值字符:字母、空格、字符,可以直接匹配自身,可以理解为精准匹配
2)特殊字符
? 一次或根本不 "(\w)?.txt" 以.txt结尾,且.前面只有一个字符
* 零次或一次或多次 "(\w)*.txt " 以.txt结尾的所有文件
+ 一次或多次
3)字符类(默认匹配一个字符)
[abc] | 其中一个 |
[^abc] | 不包括这三个 |
[a-zA-Z] | |
[a-d][m-p] | |
[a-d&&[^bc]] | |
[a-z&&[^m-p]] |
4)元字符(默认匹配一个字符)
\d | 0-9 |
\D | 非0-9 |
\w | 数字字母下划线 |
\W | 非数字字母下划线 |
\s | 空白字符 |
\S | 非空白字符 |
5)贪婪的量词(匹配多个字符)
{n} | n个 |
{n,} | n个及以上 |
{n,m} | n-m个 |
6)边界符号
^ | 匹配字符串开始的位置 |
$ | 匹配字符串结束的位置 abc$匹配字母abd并以abc结尾 |
\b | 匹配单词边界 |
\B | 匹配非单词边界 |
7)分组和捕获
() | 用于分组和捕获子表达式 |
(?:) | 用于分组但不捕获子表达式 |
8)特殊字符
I) \ 转义字符
II) . 匹配任意字符,匹配除换行符(\n、\r)之外的任何单个字符,相当于[^\n\r]
III) | 用于指定多个模式的选择
3、字符串的替换
str.replacdAll("\\d{11}","\n") | 将字符串中的连续的11个数字转化成换行符 |
4、判断
"0.0.0".matches("\\d{1,}[\\.]\\d{0,2}")
判断前面的字符串"0.0.0"格式是否符合金额
正则表达式解释:
在"."前面至少有一位小数
在"."后面最多有两位数
只有一个"."
5、补充
str1.matches("\\bhe"); 前方匹配单词边界,精准匹配
str1.matches("he\\b"); 后方匹配单词边界,精准匹配
str1.matches("\\Bll"); 中间匹配非单词边界,精准匹配
str1.replaceAll(" bhe","");
"^d[113$"
对于matches是对前方的字符串进行精准匹配,而replaceAll是对前方字符串进行模糊匹配,但如果在应用的过程中字符串以^开头$结尾,则为精准匹配
6、应用:去除字符串前后空格
"(\\s)+([\\S\\s]+(\\S)+)(\\s)+" str.replaceAll(regex,"$2")
str.replaceAll("^\\s+|\\s+$","");
str.replaceAll("^(\\s*)|(\\s*)$","");
五、集合
1、集合的约束
集合的约束依靠泛型"<>",仅支持引用数据类型,对于基本数据类型并不支持,集合中存储的都是对象的地址
2、Collection
1)List
I)ArrayList
有序,可重复,有索引
list.add(java");
list.clear();
list.remove(java");
list.contaions("java");
list.isEmpty(0);
list.size();
Objectl] objs = list.toArray();
list.get(i); 遍历会用到
list.indexOf("java");==遍历方法==
1、方法一 迭代器法
//正向调用 lterator<String> its = list.iterator(); while (its.hasNext()) { System.out.println(its.next()); } //反向调用(当指针走到最后一个元素以后) Listlterator<String> its1 = list.listlterator(); while (its1.hasPrevious(){ System.out.println(its1.previous()); }
NoSuchElementException 没有这个元素异常
当我们的指针访问越界的时候就会出现这样的问题2、方法二 增强for
//应用于数组和集合 for (String str : list) { System.out.println(str); }
3、方法三lamda表达式
list.forEach(new Consumer<String>() { @Override public void accept(String str) { System.out.println(str); ] }); list.forEach(str -> System.out.println(str)); list.forEach(System.out::println); 两种lambda表达式简化
关于ArrayList集合的底层:数组
List特有的
Collection接口
II)LinkedList
有序,可重复,有索引
关于LinkedList集合的底层:链表
对于集合的遍历,如果采用for循环遍历需要从后往前遍历,也可以采用while循环遍历
Deque接口方法Deque<String> dq =new LinkedList<String>();
dq.push("java");
dq.pop();Queue接口方法
Queue<Integer> list = new LinkedList<Integer>();
list.offer(11);
list.poll() ;
III)ArrayList和LinkeList,前者底层是数组,后者底层是链表,前者遍历快,增删慢;后者增删快,遍历慢
2)Set
I)HashSet 无序,不重复,无索引
LinkedHashSet有序,不重复,无索引
方法
Set<String> set = new HashSet<>0);
set.add("java");
底层原理HashMap
II)TreeSet
按照大小默认升序排序、不重复、无索引
Set<Student> set2 = new TreeSet<>((o1,o2)-> o1.getAge() - o2.getAge()
);
匿名内部类
实例化对象实现Comparable<Student>接口,重写compareTo()方法
对实例化对象,我们需要自定义比较规则(两种方法)
III)ClassCastException 类型转换异常
3、Map
1)无序、不重复 (覆盖)、无索引,不重复指的是键不能重复
2)HashMap
1、方法
Map<String,Integer> map = new HashMap<>(); //存入数据 map.put("数学",99); //清空集合 map.clear(); map.isEmpty(); //通过键获取值 map.get("数学"); //是否包含键 map.containsKey("数学"); //是否包含值 map.containsValue(85); //集合 map
2、遍历
原则:获取所有键,通过遍历键,拿到值
方法一:增强for Set<String> strs = map.keySet(); for (String str : strs) { System.out.println(str + ":" + map.get(str)); } 方法二 Set<Map.Entry<String, nteger> > entries = map.entrySet(); for (Map.Entry<String, Integer> entry : entries) { // System.out.println(entry); System.out.println(entry.getKey() + ":"+ entry.getValue()); }
3、底层原理:数组+链表
外层数组(默认长度为16),数组内部存放链表,链表长度过长,会转化为红黑树
链表长度达到8转为红黑树,低于6转回链表
链表扩容会扩容到原来的两倍
加载因子:0.75*原长度 如果大于了这个数就扩容
4、LinkedHashMap
方法
Map<String,Integer> map = new LinkedHashMap<>();
map.put("数学",100);
5、对于HashMap,存储数据快,但不安全
3)Hashtable
1、存储数据慢,安全
2、Properties 方法
Properties properties = new Properties(); //查询属性中所有的键值对 properties.list(System.out); //存一个键值对 properties.setProperty("JiangTian","My Bone say,l still love you ..."); //根据键取出值 System.out.println(properties.getProperty(”江添”)); //写入 Properties properties = new Properties(); properties.store(new FileOutputStream("d:/Test.txt"),"注释"); properties.store(new FileOutputStream("d:/Test2.properties"),"注释"); //取出 Properties properties2 = new Properties(); properties2.load(new FilelnputStream("d:/Test.txt")); System.out.println(properties2.getProperty("JiangTian"));
4)SortedMap:TreeMap
5)WeakHashMap
带有弱键:因为它带有弱键,每当垃圾回收的时候,对象里面的内容均清空
方法:
Map<StudentInteger> map1 = new WeakHashMap<>0; map1.put(new Student("江添",22),1); //垃圾回收 System.gc();
6)IdentityHashMap
1、方法
Map<String,Integer> map2 = new IdentityHashMap<>0: map2.put("数学",100); map2.put(new String("数学"),88);
2、这个类特殊的地方在于对于“不重复”的定义,别的实现类都是==和equals(方法均判定为不重复才能够存进去,但对于本实现类,只需要==不满足即可,也就是说,对于对象类,只要存储的地址不相等,就会判定为不相等,对内容不加约束