day25
集合框架图
标红为已经学习内容
LinkedHashMap
使用
注意:LinkedHashMap是HashMap的子类,HashMap如何使用,LinkedHashMap就怎么使用!!!
特点
特点:有序+key去重
LinkedHashMap<String, Integer> map = new LinkedHashMap<>();
map.put("麻生希", 27);
map.put("椎名空", 23);
map.put("北岛玲", 23);
map.put("水菜丽", 28);
map.put("水菜丽", 29);
map.put("水菜丽", 30);
//不清楚entrySet,查看HashMap注意事项
Set<Entry<String,Integer>> entrySet = map.entrySet();
for (Entry<String, Integer> entry : entrySet) {
System.out.println(entry);
}
Hashtable
使用
注意:Hashtable和HashMap都是实现Map接口,使用一样
特点
特点:无序+key去重+线程安全
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);
}
ConcurrentHashMap
使用
注意:ConcurrentHashMap和HashMap都是实现Map接口,使用一样
特点
特点:无序+key去重+线程安全
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);
}
HashMap vs LinkedHashMap vs Hashtable vs ConcurrentHashMap
//区别一:存储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)
TreeMap
使用
注意:TreeMap和HashMap都是实现Map接口,使用一样
特点
针对于key进行自然排序(针对String类型字典排序,Intenger类型升序)
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);
}
内置比较器:Comparable - compareTo()
使用
需求:创建学生类,将学生类的对象添加到TreeSet中
Comparable接口中的compareTo方法是排序用的,重写compareTo方法根据自己需求编写
(测试发现是去重的)
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("白白白", '男', 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>{
.......
//排序规则:按照年龄排序
@Override
public int compareTo(Student o) {
//this表示添加到TreeSet中的学生对象
//o表示TreeSet中的学生对象
return this.age - o.age;
//返回0,相同已存在不存;返回负数,小排前存;返回负数,大排后存
}
}
外置比较器:Comparator - compare()
使用
需求:将学生类的对象添加到TreeSet中
场景 - 联合开发:
1.Student类是A开发的
2.B要把Student类的对象添加到TreeSet中,但是Student的排序规则不满足B的需求
3.B想的是按照名字长度排序,长度一致按照年龄排序
注意:
在实际开发中不要轻易去改动别人写的类
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("白白白", '男', 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);
}
TreeMap vs TreeSet
TreeSet:单值
TreeMap:键值对
Properties
应用场景:
配置文件(后续连接数据库)
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
Collections
理解:集合的工具类
方法注意是针对Collection家族,少有Map家族
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);