一、Map集合概述和使用
1、Map集合是一种双列集合,每个元素包含两个数据。
2、Map集合的每个元素的格式:key=value(键值对元素)。
3、Map集合也被称为“键值对集合”。
4、Map集合的具体格式:
{key1=value1,key2=value2,key3=value3,……}
Map本身是一个接口,要使用Map需要通过子类进行对象实例化。
如声明:Map<String, Integer> maps = new HashMap<>();//多态写法
注意:一对键值对是一个元素。
二、Map集合的体系特点
1、Map集合的特点都是由键决定的。
2、Map集合的键是无序、不重复、无索引的,值不做要求(可重复)。
3、Map集合后面重复的键对应的值会覆盖前面重复键的值。
4、Map集合的键值对都可以为null。
Map集合实现类特点
1、HashMap:元素按照键是无序、不重复、无索引的,值是不做要求。(与Map体系一致)
2、LinkedHasMap:元素按照键是有序、不重复、无索引的,值不做要求。
3、TreeMap:元素按照键是排序、不重复、无索引的,值不做要求。
三、Map集合常用API
四、Map集合的遍历方式
1、遍历方式一:
例子:
public static void main(String[] args) {
//创建Map集合
Map<String ,String > map = new HashMap<>();
//存储键值对
map.put("001","张三");
map.put("002","李四");
map.put("003","王五");
//获取键集
Set<String> keySet = map.keySet();
for(String key :keySet){
//根据键获取值
String value = map.get(key);
System.out.println(key+"==>"+value);
}
}
运行结果:
001==>张三
002==>李四
003==>王五
2、遍历方式二:
public static void main(String[] args) {
//创建Map集合
Map<String ,String > map = new HashMap<>();
//存储键值对
map.put("001","张三");
map.put("002","李四");
map.put("003","王五");
//获取键值对集合
Set<Map.Entry<String,String>> entrySet = map.entrySet();
for(Map.Entry<String,String> entry : entrySet){
//entry代表一对键值对 分别获取键和值
String key = entry.getKey();
String value = entry.getValue();
System.out.println(key +"==>" + value);
}
}
运行结果:
001==>张三
002==>李四
003==>王五
3、遍历方式三:
public static void main(String[] args) {
//创建Map集合
Map<String ,String > map = new HashMap<>();
//存储键值对
map.put("001","张三");
map.put("002","李四");
map.put("003","王五");
map.forEach(new BiConsumer<String, String>() {
@Override
public void accept(String s, String s2) {
System.out.println(s +"==>" + s2);
}
});
}
运行结果:
001==>张三
002==>李四
003==>王五
其他具体实现类:
练习:
题目:
计算一个字符串中每个字符出现次数。
分析:
- 获取一个字符串对象
- 创建一个Map集合,键代表字符,值代表次数。
- 遍历字符串得到每个字符。
- 判断Map中是否有该键。
- 如果没有,第一次出现,存储次数为1;如果有,则说明已经出现过,获取到对应的值进行++,再次存储。
- 打印最终结果
代码:
public class MapTest {
public static void main(String[] args) {
//友情提示
System.out.println("请录入一个字符串:");
String line = new Scanner(System.in).nextLine();
// 定义 每个字符出现次数的方法
findChar(line);
}
private static void findChar(String line) {
//1:创建一个集合 存储 字符 以及其出现的次数
HashMap<Character, Integer> map = new HashMap<Character, Integer>();
//2:遍历字符串
for (int i = 0; i < line.length(); i++) {
char c = line.charAt(i);
//判断 该字符 是否在键集中
if (!map.containsKey(c)) {//说明这个字符没有出现过
//那就是第一次
map.put(c, 1);
} else {
//先获取之前的次数
Integer count = map.get(c);
//count++;
//再次存入 更新
map.put(c, ++count);
}
}
System.out.println(map);
}
}
五、异常
1、异常体系
a、Throwable 是所有异常的祖先,Throwable有两个子类,Error和Exception;
b、Error是错误,表示运行应用程序中出现了严重错误,都是通过Error抛出的,一般程序无法处理;
c、Exception是异常,表示程序运行的时候,程序本身可以捕获并可以处理的错误;
d、常见运行时异常:
e、编译时异常:
2、编译时异常的处理
a、出现异常直接抛出去给调用者,调用者也继续抛出去。
b、出现异常自己捕获处理,不麻烦别人。
c、前两者结合,出现异常直接抛出去给调用者,调用者捕获异常。
第一种——throws
格式:
方法 throws 异常1,异常2,异常3....{
}
规范做法:
方法 throws Exception{
}
第二种——try...catch...
a、监视捕获异常,用在方法内部,可以将方法内部出现的异常直接捕获处理。
b、这种方法还可以,发生异常的方法自己独立完成异常的处理,程序可以继续往下执行。
建议格式:
try{
}catch(Exception e){
e.printStackTrace();
}
//Exception 可以捕获处理一切异常类型!!
finally关键字:无论是否发生异常,代码总被执行;
3、运行时异常的处理
a、运行时异常编译阶段不会出错,是运行时才可能出错的,所以编译阶段不处理也可以。
b、按照规范建议还是处理:建议在最外层调用处集中捕获处理即可
4、自定义异常
创建自定义异常的步骤:
a、创建自定义异常类;
b、在方法中通过throw关键字抛出异常对象;
c、在方法声明处通过throws,指明要跑抛出给方法调用者异常,继续进行下一步操作。
d、再出现异常方法的调用者中捕获并处理异常