Day 19
一、HashTable(了解)
1.1 定义
- 此类实现一个哈希表,该哈希表将键映射到相应的值。任何非
null
对象都可以用作键或值。 - 为了成功地在哈希表中存储和获取对象,用作键的对象必须实现
hashCode
方法和equals
方法。 Hashtable
是同步的
1.2 和HashMap比较
- HashMap速度比较快,线程不同步,jdk1.2加入
- HashTable线程安全,速度较慢,jdk1.0加入,jdk1.2改进
二、Properties(掌握)
2.1 定义
Properties
类表示了一个持久的属性集。- 可保存在流中或从流中加载。
- 属性列表中每个键及其对应值都是一个字符串。
- 后面做项目肯定用得到,一定要掌握
2.2 创建对象
构造方法摘要
Properties()
创建一个无默认值的空属性列表。
Properties(Properties defaults)
创建一个带有指定默认值的空属性列表。
package com.qf.map;
import java.util.Properties;
public class Demo03 {
public static void main(String[] args) {
/**
* 构造方法摘要
Properties()
创建一个无默认值的空属性列表。
Properties(Properties defaults)
创建一个带有指定默认值的空属性列表。
*/
Properties properties = new Properties();
Properties properties2 = new Properties(properties);
System.out.println(properties);
}
}
2.3 常用方法
- 设置和获取属性
package com.qf.map;
import java.util.Properties;
public class Demo04 {
public static void main(String[] args) {
Properties properties = new Properties();
// 设置和获取properties中的属性
properties.setProperty("username", "java2005");
properties.setProperty("password", "2005java");
System.out.println(properties);
properties.setProperty("password", "chuangqianmingyueguang");
System.out.println(properties);
}
}
- 导入外部配置文件
package com.qf.map;
import java.io.File;
import java.io.FileInputStream;
import java.util.Properties;
public class Demo05 {
public static void main(String[] args) throws Exception {
// 从外部导入配置文件
Properties properties = new Properties();
properties.load(new FileInputStream(new File("info.properties")));
System.out.println(properties);
System.out.println(properties.getProperty("user"));
System.out.println(properties.getProperty("password"));
}
}
三、TreeMap(掌握)
3.1 定义
- TreeMap是Map的一个实现类
- 基于红黑树(Red-Black tree)的
NavigableMap
实现。 - 该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的
Comparator
进行排序,具体取决于使用的构造方法。 - 此实现不是同步的。
3.2 创建对象
构造方法摘要
TreeMap()
使用键的自然顺序构造一个新的、空的树映射。
TreeMap(Comparator<? super K> comparator)
构造一个新的、空的树映射,该映射根据给定比较器进行排序。
TreeMap(Map<? extends K,? extends V> m)
构造一个与给定映射具有相同映射关系的新的树映射,该映射根据其键的自然顺序 进行排序。
TreeMap(SortedMap<K,? extends V> m)
构造一个与指定有序映射具有相同映射关系和相同排序顺序的新的树映射。
package com.qf.map;
import java.util.TreeMap;
public class Demo06 {
public static void main(String[] args) {
/**
* 构造方法摘要
TreeMap()
使用键的自然顺序构造一个新的、空的树映射。
TreeMap(Comparator<? super K> comparator)
构造一个新的、空的树映射,该映射根据给定比较器进行排序。
TreeMap(Map<? extends K,? extends V> m)
构造一个与给定映射具有相同映射关系的新的树映射,该映射根据其键的自然顺序 进行排序。
TreeMap(SortedMap<K,? extends V> m)
构造一个与指定有序映射具有相同映射关系和相同排序顺序的新的树映射。
*/
TreeMap<String, String> map = new TreeMap<String, String>();
map.put("Jack", "偷心的飞贼");
map.put("Rose", "富商的妻子,被Jack拐走了");
map.put("Tony", "国际知名发型设计师");
map.put("Peter", "国际知名渣男、骗子");
System.out.println(map);
// 使用有参数的构造方法,把其他的map集合中的数据放入新创建的map集合,需要保证泛型的一致
TreeMap<String, String> map02 = new TreeMap<String, String>(map);
System.out.println(map02);
map.put("赵丽颖", "知名演员,出演过花千骨等影视剧...");
System.out.println(map);
System.out.println(map02);
}
}
3.3 TreeMap集合元素的排序
- 按照自然顺序
package com.qf.map;
import java.util.TreeMap;
public class Demo07 {
public static void main(String[] args) {
TreeMap<Integer, String> map = new TreeMap<Integer, String>();
map.put(10010, "中国联通的服务号码,经常联不通...");
map.put(10011, "中国联通话费服务号码,充钱很迅速...");
map.put(10000, "一万号,中国电信的服务号码...");
map.put(10086, "中国移动的服务号码....");
System.out.println(map);
TreeMap<String, String> map02 = new TreeMap<String, String>();
map02.put("zhangsan", "中国知名度最高的一个人");
map02.put("lisi", "中国知名度最高的一个人的铁杆搭档");
map02.put("wangwu", "和王老五很像");
map02.put("zhaoliu", "不知道是谁的一个人");
System.out.println(map02);
TreeMap<Stu, String> map03 = new TreeMap<Stu, String>();
map03.put(new Stu("libai", 33), "撒贝宁媳妇也叫李白,长得很白...");
map03.put(new Stu("zhaosi", 44), "尼古拉斯*赵四,亚洲舞王,主要看气质...");
map03.put(new Stu("songxiaobao", 35), "东北民间艺术团台柱子,本山大叔很喜欢的一个徒弟...");
System.out.println(map03);
}
}
class Stu{
String name;
int age;
public Stu(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Stu [name=" + name + ", age=" + age + "]";
}
}
- 类实现Comparable接口,重写compareTo方法
package com.qf.map;
import java.util.TreeMap;
public class Demo08 {
public static void main(String[] args) {
TreeMap<Student, String> map = new TreeMap<Student, String>();
map.put(new Student("songjiang", 48), "及时雨、呼保义、孝义黑三郎");
map.put(new Student("lujunyi", 45), "天罡星,玉麒麟");
map.put(new Student("wuyong", 62), "天机星,智多星");
map.put(new Student("gongsunsheng", 32), "天闲星,入云龙");
System.out.println(map);
}
}
class Student implements Comparable<Student>{
String name;
int age;
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
@Override
public int compareTo(Student o) {
int ret = this.name.length() - o.name.length();
if (ret == 0) {
ret = this.age - o.age;
}
return ret;
}
}
- 创建map集合的时候传入比较器
package com.qf.map;
import java.util.Comparator;
import java.util.TreeMap;
public class Demo09 {
public static void main(String[] args) {
TreeMap<Stu, String> map03 = new TreeMap<Stu, String>(new Comparator<Stu>() {
@Override
public int compare(Stu s1, Stu s2) {
int ret = s1.age - s2.age;
if (ret == 0) {
ret = s1.name.compareTo(s2.name);
}
return ret;
}
});
map03.put(new Stu("libai", 33), "撒贝宁媳妇也叫李白,长得很白...");
map03.put(new Stu("zhaosi", 44), "尼古拉斯*赵四,亚洲舞王,主要看气质...");
map03.put(new Stu("songxiaobao", 35), "东北民间艺术团台柱子,本山大叔很喜欢的一个徒弟...");
System.out.println(map03);
}
}
3.4 TreeMap增删改查的方法
package com.qf.map;
public class Demo10 {
public static void main(String[] args) {
/**
* 增
* put
* putAll
* 删
* remove
* clear
* Map.Entry<K,V> pollFirstEntry()
移除并返回与此映射中的最小键关联的键-值映射关系;如果映射为空,则返回 null。
Map.Entry<K,V> pollLastEntry()
移除并返回与此映射中的最大键关联的键-值映射关系;如果映射为空,则返回 null。
* 改
* put
* putAll
*
* 查
* Map.Entry<K,V> ceilingEntry(K key)
返回一个键-值映射关系,它与大于等于给定键的最小键关联;如果不存在这样的键,则返回 null。
K ceilingKey(K key)
返回大于等于给定键的最小键;如果不存在这样的键,则返回 null。
boolean containsKey(Object key)
如果此映射包含指定键的映射关系,则返回 true。
boolean containsValue(Object value)
如果此映射为指定值映射一个或多个键,则返回 true。
Set<Map.Entry<K,V>> entrySet()
返回此映射中包含的映射关系的 Set 视图。
Map.Entry<K,V> firstEntry()
返回一个与此映射中的最小键关联的键-值映射关系;如果映射为空,则返回 null。
K firstKey()
返回此映射中当前第一个(最低)键。
Map.Entry<K,V> floorEntry(K key)
返回一个键-值映射关系,它与小于等于给定键的最大键关联;如果不存在这样的键,则返回 null。
K floorKey(K key)
返回小于等于给定键的最大键;如果不存在这样的键,则返回 null。
V get(Object key)
返回指定键所映射的值,如果对于该键而言,此映射不包含任何映射关系,则返回 null。
Map.Entry<K,V> higherEntry(K key)
返回一个键-值映射关系,它与严格大于给定键的最小键关联;如果不存在这样的键,则返回 null。
K higherKey(K key)
返回严格大于给定键的最小键;如果不存在这样的键,则返回 null。
Set<K> keySet()
返回此映射包含的键的 Set 视图。
Map.Entry<K,V> lastEntry()
返回与此映射中的最大键关联的键-值映射关系;如果映射为空,则返回 null。
K lastKey()
返回映射中当前最后一个(最高)键。
Map.Entry<K,V> lowerEntry(K key)
返回一个键-值映射关系,它与严格小于给定键的最大键关联;如果不存在这样的键,则返回 null。
K lowerKey(K key)
返回严格小于给定键的最大键;如果不存在这样的键,则返回 null。
int size()
返回此映射中的键-值映射关系数。
Collection<V> values()
返回此映射包含的值的 Collection 视图。
*
*/
}
}
四、异常(掌握)
4.1 定义
- 程序运行的过程中出现了意外的情况,导致程序终止
- 异常处理的必要性
- 不处理程序无法向下运行
- 导致很大的损失
4.2 异常分类
- Throwable
Throwable
类是 Java 语言中所有错误或异常的超类。- 只有当对象是此类(或其子类之一)的实例时,才能通过 Java 虚拟机或者 Java 语句抛出。
- 类似地,只有此类或其子类之一才可以是 子句中的参数类型。
- Error
- 错误
- 无法挽救的错误
- 一般是系统级或者硬件级别的错误
- Exception
- 异常,程序编写、运行过程中产生的不正常的情况
- 可以抢救一下
- RuntimeException
- CheckedException
4.3 异常的产生
- 自动抛出异常
- 语法错误、参数错误,jvm无法处理,抛出异常
- 手动抛出异常
- 自己认为代码、参数不正常,手动抛出异常
- throw new 异常(异常参数)
4.4 异常的传递
- 异常产生的方法把异常传递给这个方法的调用者
- 一次向上传递
- 如果都没有处理,jvm就会抛出异常,终止程序
package com.qf.exc;
public class Demo02 {
public static void main(String[] args) {
System.out.println("main方法开始执行");
// main方法接收到show01的异常,传递给jvm,jvm说:你们都不处理,那就一起死了吧,好开心~_~
show01();
System.out.println("main方法执行结束");
}
private static void show01() {
System.out.println("show01方法开始执行");
// show01接收到show02的异常,在传递给main
show02();
System.out.println("show01方法执行结束");
}
private static void show02() {
System.out.println("show02方法开始执行");
// show02接收到show03的异常,在传递给show01
show03();
System.out.println("show02方法执行结束");
}
private static void show03() {
System.out.println("show03方法开始执行");
// show03的异常传递给直接调用者show02
System.out.println("正在进行一项伟大的工作:输出Hello World!".charAt(110));
System.out.println("show03方法执行结束");
}
}
五、异常的处理(掌握)
5.1 继续向上抛出
- 使用关键字throws在方法的声明后面表示要抛出的异常
package com.qf.exc;
public class Demo04 {
public static void main(String[] args) throws Exception {
show01();
}
private static void show01() throws Exception {
show02();
}
private static void show02() throws Exception {
show03();
}
// 向上抛出异常,谁调用谁处理
private static void show03() throws Exception{
System.out.println("haha".charAt(110));
}
}
5.2 使用try…catch处理
package com.qf.exc;
public class Demo03 {
public static void main(String[] args) {
System.out.println("HelloWorld! 000");
System.out.println("HelloWorld! 111");
System.out.println("HelloWorld! 222");
System.out.println("HelloWorld! 333");
System.out.println("HelloWorld! 444");
try {
// 尝试运行可能产生错误的代码
System.out.println(10/0);
} catch(ArithmeticException e) {
System.err.println("10/0 是算术运算异常............");
e.printStackTrace();
}
System.out.println("HelloWorld! 555");
System.out.println("HelloWorld! 666");
System.out.println("HelloWorld! 777");
System.out.println("HelloWorld! 888");
System.out.println("HelloWorld! 999");
}
}
5.3 异常处理的情况
try{}catch(){}
package com.qf.exc;
import java.util.Scanner;
public class Demo05 {
public static void main(String[] args) {
/**
* try{
* 尝试运行可能报错的代码
* }catch(可能产生的异常类 异常对象名称){
* 对异常的处理的代码
* }
*/
Scanner in = new Scanner(System.in);
System.out.println("请输入被除数:");
try {
int i01 = in.nextInt();
System.out.println("请输入除数:");
int i02 = in.nextInt();
System.out.println(i01 / i02);
}catch(Exception e) {
e.printStackTrace();
}
}
}
try{}catch(){}catch(){}…
package com.qf.exc;
import java.util.InputMismatchException;
import java.util.Scanner;
public class Demo06 {
public static void main(String[] args) {
/**
* try{
* 尝试运行可能报错的代码
* }catch(异常01 异常01对象){
*
* }catch(异常02 异常02对象){
*
* }catch(异常03 异常03对象){
*
* }catch..........{
*
* }
*/
Scanner in = new Scanner(System.in);
System.out.println("请输入被除数:");
try {
int i01 = in.nextInt();
System.out.println("请输入除数:");
int i02 = in.nextInt();
int ret = i01 / i02;
System.out.println(ret);
}catch (InputMismatchException e1) {
System.err.println("输入的数据类型有误");
}catch (ArithmeticException e) {
System.err.println("被除数不能是0");
}catch (Exception e) {
System.err.println("未知异常,你太厉害啦啦啦啦啦");
}
}
}
try{}catch(){}…finally{}
package com.qf.exc;
import java.util.InputMismatchException;
import java.util.Scanner;
public class Demo07 {
public static void main(String[] args) {
/**
* 异常处理的过程中可能会产生新的异常,需要有一段代码无论如何都要被执行到
* try{
* 可能产生异常的代码
* }catch(){
* 处理异常
* }......{
*
* }finally{
* 无论如何都能被执行的代码
* 做一些必须要执行的工作
* 比如关闭连接、释放资源
*
* }
*/
Scanner in = new Scanner(System.in);
System.out.println("请输入被除数:");
try {
int i01 = in.nextInt();
System.out.println("请输入除数:");
int i02 = in.nextInt();
int ret = i01 / i02;
System.out.println(ret);
} catch (InputMismatchException e) {
System.err.println("输入数据有误");
// return和finally会不会冲突
// return;
// 会不会影响finally执行?????????????、
System.exit(0);
} catch (ArithmeticException e) {
// 处理异常过程中再次产生异常
System.out.println(10 / 0);
System.err.println("除数不能为0");
}catch (Exception e) {
System.err.println("未知异常...");
}finally {
// 即便是前面有return,finally依旧会执行
// 如果在之前遇到了结束虚拟机的操作,finally讲不会被执行
System.out.println("main方法运行结束,资源释放,连接断开");
}
}
}
5.4 异常处理的嵌套
- 在处理异常的过程中有可能产生新的异常
- 需要在异常处理的代码中处理新的异常
- 这个称谓异常处理的嵌套
5.5 方法重写中的异常
- 子类在重写父类方法的视乎,如果父类中的方法抛出了异常
- 子类重写方法的时候不能抛出比父类范围更大的异常
package com.qf.exc;
import java.util.InputMismatchException;
import java.util.Scanner;
public class Demo08 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("请输入被除数:");
try {
// 可能出现的异常情况很多,需要具体分析
int i01 = -1;
try {
i01 = in.nextInt();
}catch (InputMismatchException e) {
System.out.println("被除数数据类型异常");
}
int i02 = -1;
try {
System.err.println("请输入除数:");
i02 = in.nextInt();
}catch (InputMismatchException e) {
System.err.println("除数数据类型异常");
}
int ret = 0;
try {
ret = i01 / i02;
System.out.println(ret);
}catch (ArithmeticException e) {
System.err.println("除数不能为0...");
System.out.println("除数能为0,没有运算结果,请手动赋值:");
try {
ret = in.nextInt();
} catch (Exception e2) {
System.out.println("手动赋值出现异常,给默认值666");
ret = 666;
}
}
}catch (Exception e) {
System.out.println("未知异常...");
}finally {
// 即便是前面有return,finally依旧会执行
// 如果在之前遇到了结束虚拟机的操作,finally讲不会被执行
System.out.println("main方法运行结束,资源释放,连接断开");
}
}
}
六、自定义异常(了解)
-
系统提供的异常不能满足用户的个性化需求
-
可以通过继承Exception或者RuntimeException来自定义异常
-
从父类调用有massage的构造方法
package com.qf.exc; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; public class Demo09 { public static void main(String[] args) { Student s01 = new Student(); s01.setName("zhangsan"); s01.setAge(23); System.out.println(s01); Student s02 = new Student(); s02.setName("lisisi"); s02.setAge(88); System.out.println(s02); } } class AgeOutofBoundsException extends RuntimeException{ public AgeOutofBoundsException() { super(); } public AgeOutofBoundsException(String message) { super(message); } } class Student{ private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { if (age >= 12 && age <= 80) { this.age = age; }else { throw new AgeOutofBoundsException("年龄不合法"); } } public Date show() throws ParseException { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); return sdf.parse("2020-08-20"); } @Override public String toString() { return "Student [name=" + name + ", age=" + age + "]"; } } class BigStudent extends Student{ @Override public Date show() throws ParseException{ return super.show(); } }