Day29 集合的常用类
文章目录
- Day29 集合的常用类
- 一、Collections
- 二、 ConcurrentHashMap
- 三、HashMap vs LinkedHashMap vs Hashtable vs ConcurrentHashMap
- 四、LinkedHashMap
- 五、Properties
一、Collections
1、概念:
java.util.Collections
是Java集合框架中的一个实用类,提供了一系列静态方法,用于对集合进行各种操作,如排序、查找、同步等。
2、理解:集合的工具类,
3、功能:
- 集合排序:
sort(List list)
:对列表进行排序,要求列表中的元素必须实现Comparable接口。sort(List list, Comparator c)
:使用指定的比较器对列表进行排序。
- 查找和替换:
binarySearch(List list, T key)
:对列表进行二分查找,要求列表已经按照自然顺序排序。binarySearch(List list, T key, Comparator c)
:使用指定的比较器对列表进行二分查找。replaceAll(List list, T oldVal, T newVal)
:将列表中所有等于oldVal的元素替换为newVal。
- 同步控制:
synchronizedCollection(Collection c)
:返回指定集合的同步(线程安全)视图。synchronizedList(List list)
:返回指定列表的同步(线程安全)视图。synchronizedMap(Map m)
:返回指定映射的同步(线程安全)视图。
- 不可变集合:
unmodifiableCollection(Collection c)
:返回指定集合的不可修改视图。unmodifiableList(List list)
:返回指定列表的不可修改视图。unmodifiableMap(Map m)
:返回指定映射的不可修改视图。
- 其他:
reverse(List list)
:反转列表中元素的顺序。shuffle(List list)
:随机重排列表中的元素。
4、举例:
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>() {@Overridepublic int compare(Integer o1, Integer o2) {//return o2-o1;return Integer.compare(o2, o1);}});//将list封装成线程安全的ListList<Integer> synchronizedList = Collections.synchronizedList(list);System.out.println(synchronizedList);}
二、 ConcurrentHashMap
1、概念:
ConcurrentHashMap
是Java集合框架中的一个线程安全的哈希表实现类,用于在多线程环境下进行并发访问。与传统的HashMap
相比,ConcurrentHashMap
提供了更好的并发性能和线程安全性。
2、特点:(无序+key去重+线程安全)
- 线程安全:
ConcurrentHashMap
内部使用分段锁(Segment)来保证线程安全,不会对整个数据结构加锁,不同段的数据可以并发访问。 - 高并发性:支持高并发的读操作和一定程度的并发写操作,适合在多线程环境下使用。
- 扩容机制:相较于传统的
HashMap
,ConcurrentHashMap
的扩容机制更加高效,不会导致整个数据结构被锁定。 - 允许空键值:与
HashMap
类似,ConcurrentHashMap
允许使用null
作为键或值。
3、应用场景:
ConcurrentHashMap适用于需要在多线程环境下进行并发访问的场景,如并发编程、多线程数据共享等。它提供了高效的并发性能和线程安全的特性,可以减少在多线程环境下出现的竞态条件和线程安全问题。
4、基本用法:
ConcurrentHashMap<KeyType, ValueType> map = new ConcurrentHashMap<>();
// 添加元素
map.put(key1, value1);
map.put(key2, value2);
// 获取元素
ValueType value = map.get(key);
// 删除元素
map.remove(key);
// 遍历元素
for (Map.Entry<KeyType, ValueType> entry : map.entrySet()) {KeyType key = entry.getKey();ValueType value = entry.getValue();// 处理键值对
}
5、举例:
public static void main(String[] args) {ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();//添加元素map.put("小希", 27);map.put("小空", 23);map.put("小丽", 28);map.put("小光", 36);map.put("小奈", 32);map.put("小阳", 28);map.put("小衣", 28);//将newMap中所有的元素添加到map集合中ConcurrentHashMap<String, Integer> newMap = new ConcurrentHashMap<>();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获取到对应的ValueInteger 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("小希"));//trueSystem.out.println("判断集合中是否有指定的value:" + map.containsValue(27));//trueSystem.out.println("判断集合中是否没有元素:" + map.isEmpty());//false//通过key删除映射关系(key+value)map.remove("aaa");//通过key+value删除映射关系(key+value)map.remove("bbb", 20);//通过key替换valuemap.replace("小希", 30);//通过key+value替换valuemap.replace("小空", 23, 25);//获取映射关系的个数(映射关系内包含了key和value)int size = map.size();System.out.println("获取映射关系的个数:" + size);//10//获取map中所有的valueCollection<Integer> values = map.values();System.out.println(Arrays.toString(values.toArray()));//将集合转换为数组,再将数组转换为字符串System.out.println("-----------------------");//遍历 -- keySet()//思路:获取map集合中所有的key放在一个Set集合中,遍历Set集合获取出key,再通过key获取到Map集合中对应的valueSet<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);}}
三、HashMap vs LinkedHashMap vs Hashtable vs ConcurrentHashMap
1、区别一:
区别一:存储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键j
ConcurrentHashMap<Object,Object> concurrentHashMap = new ConcurrentHashMap<>();concurrentHashMap.put(null, null);
2、区别二:
应用场景的区别
HashMap:无序+key去重
LinkedHashMap:有序+key去重
Hashtable:无序+key去重+线程安全(在方法上加锁,效率低,已弃用)
ConcurrentHashMap:无序+key去重+线程安全(局部加锁+CAS实现线程安全,效率高,多线程下使用ConcurrentHashMap)
四、LinkedHashMap
1、概念:
LinkedHashMap
是Java集合框架中的一个实现类,它继承自HashMap
,并且使用双向链表维护插入顺序或者访问顺序。与HashMap
不同的是,LinkedHashMap
可以保持元素的插入顺序或者访问顺序,因此在遍历时可以按照插入顺序或者访问顺序进行遍历。
2、特点:(有序+key去重)
- 保持顺序:
LinkedHashMap
可以保持元素的插入顺序或者访问顺序,因此在遍历时可以按照插入顺序或者访问顺序进行遍历。 - 性能:与
HashMap
相比,LinkedHashMap
在维护顺序的同时会略微降低插入、删除和查找的性能。 - 线程不安全:
LinkedHashMap
不是线程安全的,如果需要在多线程环境中使用,需要进行适当的同步处理。
3、基本用法:( 注意:LinkedHashMap是HashMap的子类,HashMap如何使用,LinkedHashMap就怎么使用!!!)
// 创建一个按照插入顺序排序的LinkedHashMap
LinkedHashMap<String, Integer> linkedHashMap = new LinkedHashMap<>();
// 添加元素
linkedHashMap.put("A", 1);
linkedHashMap.put("B", 2);
linkedHashMap.put("C", 3);
// 遍历元素(按照插入顺序)
for (Map.Entry<String, Integer> entry : linkedHashMap.entrySet()) {System.out.println(entry.getKey() + ": " + entry.getValue());
}
4、举例:
public static void main(String[] args) {LinkedHashMap<String, Integer> map = new LinkedHashMap<>();//添加元素map.put("小希", 27);map.put("小空", 23);map.put("小丽", 28);map.put("小光", 36);map.put("小奈", 32);map.put("小阳", 28);map.put("小衣", 28);//将newMap中所有的元素添加到map集合中LinkedHashMap<String, Integer> newMap = new LinkedHashMap<>();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获取到对应的ValueInteger 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("小希"));//trueSystem.out.println("判断集合中是否有指定的value:" + map.containsValue(27));//trueSystem.out.println("判断集合中是否没有元素:" + map.isEmpty());//false//通过key删除映射关系(key+value)map.remove("aaa");//通过key+value删除映射关系(key+value)map.remove("bbb", 20);//通过key替换valuemap.replace("小希", 30);//通过key+value替换valuemap.replace("小空", 23, 25);//获取映射关系的个数(映射关系内包含了key和value)int size = map.size();System.out.println("获取映射关系的个数:" + size);//10//获取map中所有的valueCollection<Integer> values = map.values();System.out.println(Arrays.toString(values.toArray()));//将集合转换为数组,再将数组转换为字符串System.out.println("-----------------------");//遍历 -- keySet()//思路:获取map集合中所有的key放在一个Set集合中,遍历Set集合获取出key,再通过key获取到Map集合中对应的valueSet<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);}}
五、Properties
1、概念:
Properties
是Java中用于处理属性文件的一个类,它继承自Hashtable
,并且通常用于处理应用程序的配置信息,如键值对形式的配置文件。Properties
类提供了读取和写入属性文件的方法,以及方便的操作属性的功能。
2、应用场景:配置文件
3、主要特点和用法:
-
读取属性文件:
- 使用
load(InputStream in)
方法可以从输入流中加载属性文件。
Properties prop = new Properties(); prop.load(new FileInputStream("config.properties"));
- 使用
-
获取属性值:
- 使用
getProperty(String key)
方法可以获取指定键对应的值。
String value = prop.getProperty("key");
- 使用
-
设置属性值:
- 使用
setProperty(String key, String value)
方法可以设置指定键对应的值。
prop.setProperty("key", "value");
- 使用
-
持久化属性文件:
- 使用
store(OutputStream out, String comments)
方法可以将属性存储到输出流中。
prop.store(new FileOutputStream("config.properties"), "This is a properties file.");
- 使用
-
默认值:
- 可以使用
getProperty(String key, String defaultValue)
方法获取属性值,如果属性不存在则返回默认值。
- 可以使用
4、代码理解:
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不存在,返回的为nullString 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);}
集合框架图: