Day25
1.TreeMap
1.1 TreeMap的使用
public class Test01 {
public static void main(String[] args) {
TreeMap<String, Integer> map = new TreeMap<>();
//添加元素
map.put("麻生希", 27);
map.put("椎名空", 23);
map.put("水菜丽", 28);
map.put("朝桐光", 36);
map.put("爱田奈奈", 32);
map.put("水野朝阳", 28);
map.put("波多野结衣", 28);
//将newMap中所有的元素添加到map集合中
TreeMap<String, Integer> newMap = new TreeMap<>();
newMap.put("aaa", 10);
newMap.put("bbb", 20);
newMap.put("ccc", 30);
newMap.put("ddd", 40);
map.putAll(newMap);
//如果key存在就获取value值,如果不存在就添加
Integer putIfAbsent = map.putIfAbsent("麻生希111", 28);
System.out.println("putIfAbsent:" + putIfAbsent);
//通过Key获取到对应的Value
Integer integer1 = map.get("水菜丽");
System.out.println("通过Key获取对应的value:" + integer1);//28
//通过Key获取对应的value,如果key不存在则返回默认值
Integer integer2 = map.getOrDefault("麻生希111", 888);
System.out.println("通过Key获取对应的value:" + integer2);//888
//清空集合中的元素
//map.clear();
System.out.println("判断集合中是否有指定的key:" + map.containsKey("麻生希"));//true
System.out.println("判断集合中是否有指定的value:" + map.containsValue(27));//true
System.out.println("判断集合中是否没有元素:" + map.isEmpty());//false
//通过key删除映射关系(key+value)
map.remove("aaa");
//通过key+value删除映射关系(key+value)
map.remove("bbb", 20);
//通过key替换value
map.replace("麻生希", 30);
//通过key+value替换value
map.replace("椎名空", 23, 25);
//获取映射关系的个数(映射关系内包含了key和value)
int size = map.size();
System.out.println("获取映射关系的个数:" + size);//10
//获取map中所有的value
Collection<Integer> values = map.values();
System.out.println(Arrays.toString(values.toArray()));//将集合转换为数组,再将数组转换为字符串
System.out.println("-----------------------");
//遍历 -- keySet()
//思路:获取map集合中所有的key放在一个Set集合中,遍历Set集合获取出key,再通过key获取到Map集合中对应的value
Set<String> keySet = map.keySet();
for (String key : keySet) {
Integer value = map.get(key);
System.out.println(key + " -- " + value);
}
System.out.println("-----------------------");
//遍历 -- entrySet()
//思路:获取map集合中所有的映射关系对象放在一个Set集合中,遍历Set集合获取出映射关系对象(Key+Value)
Set<Entry<String,Integer>> entrySet = map.entrySet();
for (Entry<String, Integer> entry : entrySet) {
String key = entry.getKey();
Integer value = entry.getValue();
System.out.println(key + " -- " + value);
}
}
}
1.2 TreeMap的特点
特点:针对于key进行自然排序
public class Test02 {
public static void main(String[] args) {
TreeMap<String, Integer> map = new TreeMap<>();
map.put("d", 10);
map.put("a", 20);
map.put("c", 30);
map.put("b", 40);
map.put("ac", 50);
map.put("ab", 50);
map.put("aa", 50);
Set<Entry<String,Integer>> entrySet = map.entrySet();
for (Entry<String, Integer> entry : entrySet) {
System.out.println(entry);
}
}
}
1.3 内置比较器
public class Test03 {
public static void main(String[] args) {
TreeMap<Student, String> map = new TreeMap<>();
map.put(new Student("麻生希", '女', 27, "2401", "001"),"看书");
map.put(new Student("椎名空", '女', 23, "2401", "002"),"打篮球");
map.put(new Student("水菜丽", '女', 21, "2401", "003"),"踢足球");
map.put(new Student("朝桐光", '女', 31, "2401", "004"),"打羽毛球");
map.put(new Student("北岛玲", '女', 36, "2401", "005"),"跑步");
map.put(new Student("樱井步", '女', 29, "2401", "006"),"登山");
map.put(new Student("爱田奈奈", '女', 32, "2401", "007"),"对弈");
map.put(new Student("水野朝阳", '女', 31, "2401", "008"),"闻香");
map.put(new Student("古川伊织", '女', 27, "2401", "009"),"探幽");
map.put(new Student("巴得伟", '男', 21, "2401", "010"),"侯月");
map.put(new Student("李星乐", '男', 20, "2401", "011"),"赏花");
map.put(new Student("北条麻衣", '女', 34, "2402", "001"),"听雨");
map.put(new Student("濑亚美莉", '女', 23, "2402", "002"),"扶琴");
map.put(new Student("三上悠亚", '女', 21, "2402", "003"),"写诗");
map.put(new Student("小西满里惠", '女', 31, "2402", "004"),"打游戏");
map.put(new Student("桃谷绘里香", '女', 27, "2402", "005"),"看小说");
map.put(new Student("铃原爱蜜莉", '女', 23, "2402", "006"),"唱歌");
map.put(new Student("明日花绮罗", '女', 28, "2402", "007"),"跳舞");
map.put(new Student("京香Julia", '女', 34, "2402", "008"),"美食");
map.put(new Student("巴得伟", '男', 18, "2402", "009"),"品茶");
map.put(new Student("张海杰", '男', 20, "2402", "010"),"画画");
Set<Entry<Student,String>> entrySet = map.entrySet();
for (Entry<Student, String> entry : entrySet) {
Student key = entry.getKey();
String value = entry.getValue();
System.out.println(key + " -- " + value);
}
}
}
public class Student implements Comparable<Student>{
private String name;
private char sex;
private int age;
private String classId;
private String id;
//无参构造,有参构造,get,set省略
//判断两个学生是否相同
//比较规则:班级号+学号
@Override
public boolean equals(Object obj) {
if(this == obj){
return true;
}
if(obj instanceof Student){
Student stu = (Student) obj;
if(this.classId.equals(stu.classId) && this.id.equals(stu.id)){
return true;
}
}
return false;
}
@Override
public String toString() {
return name + "\t" + sex + "\t" + age + "\t" + classId + "\t" + id;
}
//排序规则:按照年龄排序
@Override
public int compareTo(Student o) {
//this表示添加到TreeSet中的学生对象
//o表示TreeSet中的学生对象
return this.age - o.age;
}
}
1.4 外置比较器
注意:外置比较器 > 内置比较器
public class Test04 {
public static void main(String[] args) {
TreeMap<Student, String> map = new TreeMap<>(new Comparator<Student>() {
//比较规则:按照姓名长度排序,长度一致按照年龄排序
@Override
public int compare(Student o1, Student o2) {
if(o1.equals(o2)){
return 0;
}
int nameLen1 = o1.getName().length();
int nameLen2 = o2.getName().length();
if(nameLen1 != nameLen2){
return Integer.compare(nameLen1, nameLen2);
}
int age1 = o1.getAge();
int age2 = o2.getAge();
if(age1 != age2){
return Integer.compare(age1, age2);
}
return 1;
}
});
map.put(new Student("麻生希", '女', 27, "2401", "001"),"看书");
map.put(new Student("椎名空", '女', 23, "2401", "002"),"打篮球");
map.put(new Student("水菜丽", '女', 21, "2401", "003"),"踢足球");
map.put(new Student("朝桐光", '女', 31, "2401", "004"),"打羽毛球");
map.put(new Student("北岛玲", '女', 36, "2401", "005"),"跑步");
map.put(new Student("樱井步", '女', 29, "2401", "006"),"登山");
map.put(new Student("爱田奈奈", '女', 32, "2401", "007"),"对弈");
map.put(new Student("水野朝阳", '女', 31, "2401", "008"),"闻香");
map.put(new Student("古川伊织", '女', 27, "2401", "009"),"探幽");
map.put(new Student("巴得伟", '男', 21, "2401", "010"),"侯月");
map.put(new Student("李星乐", '男', 20, "2401", "011"),"赏花");
map.put(new Student("北条麻衣", '女', 34, "2402", "001"),"听雨");
map.put(new Student("濑亚美莉", '女', 23, "2402", "002"),"扶琴");
map.put(new Student("三上悠亚", '女', 21, "2402", "003"),"写诗");
map.put(new Student("小西满里惠", '女', 31, "2402", "004"),"打游戏");
map.put(new Student("桃谷绘里香", '女', 27, "2402", "005"),"看小说");
map.put(new Student("铃原爱蜜莉", '女', 23, "2402", "006"),"唱歌");
map.put(new Student("明日花绮罗", '女', 28, "2402", "007"),"跳舞");
map.put(new Student("京香Julia", '女', 34, "2402", "008"),"美食");
map.put(new Student("巴得伟", '男', 18, "2402", "009"),"品茶");
map.put(new Student("张海杰", '男', 20, "2402", "010"),"画画");
Set<Entry<Student,String>> entrySet = map.entrySet();
for (Entry<Student, String> entry : entrySet) {
Student key = entry.getKey();
String value = entry.getValue();
System.out.println(key + " -- " + value);
}
}
}
2.LinkedHashMap
2.1 LinkedHashMap的使用
注意:LinkedHashMap是HashMap的子类,HashMap如何使用,LinkedHashMap就怎么使用!!!
2.2 LinkedLinkedHashMap的特点
特点:有序+key去重
public class Test02 {
public static void main(String[] args) {
LinkedHashMap<String, Integer> map = new LinkedHashMap<>();
map.put("麻生希", 27);
map.put("椎名空", 23);
map.put("北岛玲", 23);
map.put("水菜丽", 28);
map.put("水菜丽", 29);
map.put("水菜丽", 30);
Set<Entry<String,Integer>> entrySet = map.entrySet();
for (Entry<String, Integer> entry : entrySet) {
System.out.println(entry);
}
}
}
3.Hashtable
3.1 Hashtable的使用
HashMap如何使用,Hashtable就怎么使用!!!
3.2 Hashtable的特点
特点:无序+key去重+线程安全
public class Test02 {
public static void main(String[] args) {
Hashtable<String, Integer> map = new Hashtable<>();
map.put("麻生希", 27);
map.put("椎名空", 23);
map.put("北岛玲", 23);
map.put("水菜丽", 28);
map.put("水菜丽", 29);
map.put("水菜丽", 30);
Set<Entry<String,Integer>> entrySet = map.entrySet();
for (Entry<String, Integer> entry : entrySet) {
System.out.println(entry);
}
}
}
4.ConcurrentHashMap
4.1 ConcurrentHashMap的使用
HashMap如何使用,ConcurrentHashMap就怎么使用!!!
4.2 ConcurrentHashMap的特点
特点:无序+key去重+线程安全
public class Test02 {
public static void main(String[] args) {
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
map.put("麻生希", 27);
map.put("椎名空", 23);
map.put("北岛玲", 23);
map.put("水菜丽", 28);
map.put("水菜丽", 29);
map.put("水菜丽", 30);
Set<Entry<String,Integer>> entrySet = map.entrySet();
for (Entry<String, Integer> entry : entrySet) {
System.out.println(entry);
}
}
}
5.HashMap vs LinkedHashMap vs Hashtable vs ConcurrentHashMap
区别一:存储null 键的情况
HashMap允许存储null键
LinkedHashMap允许存储null键
Hashtable不允许存储null键
ConcurrentHashMap不允许存储null键
区别二:应用场景的区别
HashMap:无序+key去重
LinkedHashMap:有序+key去重
Hashtable:无序+key去重+线程安全(在方法上加锁,效率低,已弃用)
ConcurrentHashMap:无序+key去重+线程安全(局部加锁+CAS实现线程安全,效率高,多线程下使用ConcurrentHashMap)
public class Test03 {
public static void main(String[] args) {
//区别一:存储null 键的情况
//HashMap允许存储null键
// HashMap<Object,Object> hashMap = new HashMap<>();
// hashMap.put(null, null);
//LinkedHashMap允许存储null键
// LinkedHashMap<Object,Object> linkedHashMap = new LinkedHashMap<>();
// linkedHashMap.put(null, null);
//Hashtable不允许存储null键
Hashtable<Object, Object> hashtable = new Hashtable<>();
hashtable.put(null, null);
//ConcurrentHashMap不允许存储null键
ConcurrentHashMap<Object,Object> concurrentHashMap = new ConcurrentHashMap<>();
concurrentHashMap.put(null, null);
//区别二:应用场景的区别
//HashMap:无序+key去重
//LinkedHashMap:有序+key去重
//Hashtable:无序+key去重+线程安全(在方法上加锁,效率低,已弃用)
//ConcurrentHashMap:无序+key去重+线程安全(局部加锁+CAS实现线程安全,效率高,多线程下使用ConcurrentHashMap)
}
}
6.Properties
应用场景:配置文件
将配置文件加载到配置文件对象中
底层实现:
1.将配置文件中的数据读取出
2.将键值对写入父类对象(Hashtable) – super.put(key,value)
public class Test01 {
public static void main(String[] args) throws IOException {
//创建配置文件对象
Properties p = new Properties();
/*
* 将配置文件加载到配置文件对象中
*
* 底层实现:
* 1.将配置文件中的数据读取出
* 2.将键值对写入父类对象(Hashtable) -- super.put(key,value)
*/
p.load(Test01.class.getClassLoader().getResourceAsStream("dbconfig.properties"));
//获取配置文件里的数据
//底层实现:利用父类对象(Hashtable).get(key)
String username = p.getProperty("username");
String password = p.getProperty("password");
System.out.println(username + " -- " + password);
//注意1:如果key不存在,返回的为null
String name = p.getProperty("name");
System.out.println(name);
//注意2:如果key不存在,就返回默认值
String url = p.getProperty("url", "默认值");
System.out.println(url);
//将键值对写入到父类对象中(Hashtable),并不是写入配置文件中
p.setProperty("author", "何老师");
String author = p.getProperty("author");
System.out.println(author);
}
}
dbconfig.properties文件
username=root
password=123123
7.Collections
理解:集合的工具类
public class Test01 {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
//批量添加
Collections.addAll(list, 4,7,5,1,9,2,8,3,6);
//获取最小值 -- 利用元素的内置比较器
Integer min = Collections.min(list);
System.out.println("获取最小值:" + min);
//获取最大值 -- 利用元素的内置比较器
Integer max = Collections.max(list);
System.out.println("获取最大值:" + max);
//排序 -- 利用元素的内置比较器
Collections.sort(list);
//查找 -- 使用二叉搜索算法,意味着在此调用之前必须排序
int index = Collections.binarySearch(list, 9);
System.out.println("查找到对应元素的下标:" + index);
//排序 -- 利用外置比较器
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
//return o2-o1;
return Integer.compare(o2, o1);
}
});
//将list封装成线程安全的List
List<Integer> synchronizedList = Collections.synchronizedList(list);
System.out.println(synchronizedList);
}
}
简答题
1.Collection包结构,与Collections的区别
Collection是集合类的上级接口,子接口有 Set、List、LinkedList、ArrayList、Vector、Stack、Set;
Collections是集合类的一个帮助类, 它包含有各种有关集合操作的静态多态方法,用于实现对各种集合的搜索、排序、线程安全化等操作。此类不能实例化,就像一个工具类,服务于Java的Collection框架。
2.ConcurrentHashMap的底层实现原理,以及它与Hashtable的异同吗?
ConcurrentHashMap是Java中提供的一个线程安全的HashMap实现。它通过分段锁的机制来提高并发访问的效率。具体来说,它将数据分成一段一段存储,然后给每一段数据配上一把锁。当一个线程占用锁访问其中一段数据时,其他段的数据也能被其他线程访问。
Hashtable也是线程安全的,但它是通过对整个数据结构加锁来实现的,这会导致当一个线程访问Hashtable时,其他所有线程都被阻塞,因此性能较低。
总结
1.ListHashMap
2.Hashtable
3.ConcurrentHashMap
4.HashMap vs LinkedHashMap vs Hashtable vs ConcurrentHashMap
存入null键:
HashMap – ok
LinkedHashMap – ok
Hashtable - no
ConcurrentHashMap - no应用场景:
HashMap:无序 + 去重 LinkedHashMap:有序+去重 Hashtable:无序 + 去重 + 线程安全(方法里加锁,效率低,已弃用) ConcurrentHashMap:无序+去重+线程安全(局部加锁+CAS,效率高,推荐使用)
5.TreeMap(内置比较器、外置比较器)
6.Properties – 配置文件类
7.Collections – 集合的工具类