Java基础——Map集合&&Collections工具类
注:本文讲述Java中的Map集合及Collections工具类
一、Map
目录
接口
1、概述
Map与List、Set接口不同,它是由一系列键值对组成的集合,提供了key到Value的映射。同时它也没有继承Collection。在Map中它保证了key与value之间的一一对应关系。也就是说一个key对应一个value,所以它不能存在相同的key值,当然value值可以相同。实现map的有:HashMap、TreeMap、HashTable、Properties。
| Collection集合 | 元素是孤立存在,向集合中存储元素采用一个个元素的方式存储。(单列集合顶级接口) |
| Map集合 | 元素是成对存在的(键值对(key,value))。每个元素由键与值两部分组成,通过键可以找对所对应的值。 |
需要注意的是,Map中的集合不能包含重复的键,值可以重复;每个键只能对应一个值(这个值可以是单个值,也可以是个数组或集合值)。
2、Map常用方法
| 增加操作 |
put(K key, V value); void putAll(Map<? extends K,? extends V> m)(泛型下篇讲) |
| 删除操作 |
V remove (Object key) void clear() // 清空集合 |
| 查询操作 |
V get(Object key) //通过key查询value boolean containsKey(Object key) //是否包含key boolean containsValue(Object value) // 是否包含value boolean isEmpty() //集合是否为空 |
| 元视图操作的方法 |
Set<K> keySet() //返回Map中所有键(key)组成的Set集合 Collection<V> values() // 返回Map中所有值(value)组成的Collection集合 Set<Map.Entry<K,V>> entrySet() //返回Map中所有键值对(Entry)组成的Set集合 |
| 其他方法 | int size() //用于获取Map中键值对的数量 |
tips:
使用put方法时,若指定的键(key)在集合中没有,则没有这个键对应的值,返回null,并把指定的键值添加到集合中;
若指定的键(key)在集合中存在,则返回值为集合中键对应的值(该值为替换前的值),并把指定键所对应的值,替换成指定的新值。
3、Map集合的遍历
(1)分开遍历:
单独遍历所有key / 单独遍历所有value
(2)成对遍历:
遍历的是映射关系Map.Entry类型的对象,Map.Entry是Map接口的内部接口。每一种Map内部有自己的Map.Entry的实现类。在Map中存储数据,实际上是将Key---->value的数据存储在Map.Entry接口的实例中,再在Map集合中插入Map.Entry的实例化对象
以下是几种遍历方式:
public class HashMapTest {
public static void main(String[] args) {
Map<String, String> map1 = new HashMap<>();
map1.put("郭靖","黄蓉");
map1.put("杨过","小龙女");
map1.put("张三丰","郭襄");
System.out.println("----keySet----");
Set<String> keySet = map1.keySet();
for (String s :keySet) {
System.out.println(s+"===>"+ map1.get(s));
}
HashMap<String, String> map2 = new HashMap<>();
map2.put("萧峰","阿朱");
map2.put("段誉","王语嫣");
map2.put("虚竹","梦姑");
System.out.println("----增强for循环----");
for (Map.Entry<String, String> entry : map2.entrySet()) {
System.out.println(entry.getKey()+"===>"+ entry.getValue());
}
HashMap<String, String> map3 = new HashMap<>();
map3.put("令狐冲","任盈盈");
map3.put("岳不群","宁中则");
map3.put("林平之","岳灵珊");
System.out.println("----iterator----");
Set<Map.Entry<String, String>> entrySet1 = map3.entrySet();
Iterator<Map.Entry<String, String>> iterator = entrySet1.iterator();
while (iterator.hasNext()){
Map.Entry<String, String> entry = iterator.next();
System.out.println(entry.getKey()+"===>"+ entry.getValue());
}
System.out.println("----forench----");
HashMap<String, String> map4 = new HashMap<>();
map4.put("张无忌","赵敏");
map4.put("宋青书","周芷若");
map4.put("杨逍","纪晓芙");
map4.forEach(new BiConsumer<String, String>() {
@Override
public void accept(String s, String s2) {
System.out.println(s+"===>"+s2);
}
});
}
二、Map的实现类
Map接口的常用实现类:HashMap、TreeMap、LinkedHashMap和Properties。其中HashMap是 Map 接口使用频率最高的实现类。
1、Hash和Hashtable
HashMap 也是一个基于哈希表的集合,用于存储键值对;
HashMap底层原理:
存储:
key.hashcode()%16计算存储位置;
该位置有数据比较key的hashcode和equals,为true则替换,为false则存到末位
扩容机制:
数组默认是16,超过0.75则扩容2倍
链表元素个数>8 并且 数组.length>64,则该索引位置上的链表转为红黑树

HashMap和Hashtable都是哈希表。HashMap和Hashtable判断两个 key 相等的标准是:两个 key 的hashCode 值相等,并且 equals() 方法也返回 true。因此,为了成功地在哈希表中存储和获取对象,用作键的对象必须实现 hashCode 方法和 equals 方法。
- Hashtable是线程安全的,任何非 null 对象都可以用作键或值。
- HashMap是线程不安全的,并允许使用 null 值和 null 键。
示例代码:添加员工姓名为key,薪资为value
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.Set;
public class TestHashMap {
public void test01(){
HashMap<String,Double> map = new HashMap<>();
map.put("张三", 10000.0);
//key相同,新的value会覆盖原来的value
//因为String重写了hashCode和equals方法
map.put("张三", 12000.0);
map.put("李四", 14000.0);
//HashMap支持key和value为null值
String name = null;
Double salary = null;
map.put(name, salary);
Set<Map.Entry<String, Double>> entrySet = map.entrySet();
for (Map.Entry<String, Double> entry : entrySet) {
System.out.println(entry);
}
}
public void test02(){
Hashtable<String,Double> map = new Hashtable<>();
map.put("张三", 10000.0);
//key相同,新的value会覆盖原来的value
//因为String重写了hashCode和equals方法
map.put("张三", 12000.0);
map.put("李四", 14000.0);
//Hashtable不支持key和value为null值
/*String name = null;
Double salary = null;
map.put(name, salary);*/
Set<Map.Entry<String, Double>> entrySet = map.entrySet();
for (Map.Entry<String, Double> entry : entrySet) {
System.out.println(entry);
}
}
}
2、LinkedHashMap
LinkedHashMap 是 HashMap 的子类。此实现与 HashMap 的不同之处在于,后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,该迭代顺序通常就是将键插入到映射中的顺序(插入顺序)。
示例代码:添加员工姓名为key,薪资为value
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
public class TestLinkedHashMap {
public static void main(String[] args) {
LinkedHashMap<String,Double> map = new LinkedHashMap<>();
map.put("张三", 10000.0);
//key相同,新的value会覆盖原来的value
//因为String重写了hashCode和equals方法
map.put("张三", 12000.0);
map.put("李四", 14000.0);
//HashMap支持key和value为null值
String name = null;
Double salary = null;
map.put(name, salary);
Set<Map.Entry<String, Double>> entrySet = map.entrySet();
for (Map.Entry<String, Double> entry : entrySet) {
System.out.println(entry);
}
}
}
3、TreeMap
基于红黑树(Red-Black tree)的 NavigableMap 实现。该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator 进行排序,具体取决于使用的构造方法。简单来说就是TreeMap是Map接口基于红黑树的实现;默认对key进行自然排序;
代码示例:添加员工姓名为key,薪资为value
import java.util.Comparator;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
import org.junit.Test;
public class TestTreeMap {
@Test
public void test1() {
TreeMap<String,Integer> map = new TreeMap<>();
map.put("Jack", 11000);
map.put("Alice", 12000);
map.put("zhangsan", 13000);
map.put("haogu", 14000);
map.put("Lucy", 15000);
//String实现了Comparable接口,默认按照Unicode编码值排序
Set<Entry<String, Integer>> entrySet = map.entrySet();
for (Entry<String, Integer> entry : entrySet) {
System.out.println(entry);
}
}
@Test
public void test2() {
//指定定制比较器Comparator,按照Unicode编码值排序,但是忽略大小写
TreeMap<String,Integer> map = new TreeMap<>(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.compareToIgnoreCase(o2);
}
});
map.put("Jack", 11000);
map.put("Alice", 12000);
map.put("zhangsan", 13000);
map.put("haogu", 14000);
map.put("Lucy", 15000);
Set<Entry<String, Integer>> entrySet = map.entrySet();
for (Entry<String, Integer> entry : entrySet) {
System.out.println(entry);
}
}
}
三、Collections工具类
Collections 是一个操作 Set、List 和 Map 等集合的工具类。Collections 中提供了一系列静态的方法对集合元素进行排序、查询和修改等操作,还提供了对集合对象设置不可变、对集合对象实现同步控制等方法:
| public static <T> boolean addAll(Collection<? super T> c,T... elements) | 将所有指定元素添加到指定 collection 中。 |
| public static <T> int binarySearch(List<? extends Comparable<? super T>> list,T key) | 在List集合中查找某个元素的下标,但是List的元素必须是T或T的子类对象,而且必须是可比较大小的,即支持自然排序的。而且集合也事先必须是有序的,否则结果不确定。 |
| public static <T> int binarySearch(List<? extends T> list,T key,Comparator<? super T> c) |
在List集合中查找某个元素的下标,但是List的元素必须是T或T的子类对象,而且集合也事先必须是按照c比较器规则进行排序过的,否则结果不确定。 |
| public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) | 在coll集合中找出最大的元素,集合中的对象必须是T或T的子类对象,而且支持自然排序 |
| public static <T> T max(Collection<? extends T> coll,Comparator<? super T> comp) | 在coll集合中找出最大的元素,集合中的对象必须是T或T的子类对象,按照比较器comp找出最大者 |
| public static void reverse(List<?> list) | 反转指定列表List中元素的顺序。 |
| public static void shuffle(List<?> list) | List 集合元素进行随机排序,类似洗牌 |
| public static <T extends Comparable<? super T>> void sort(List<T> list) | 根据元素的自然顺序对指定 List 集合元素按升序排序 |
| public static <T> void sort(List<T> list,Comparator<? super T> c) | 根据指定的 Comparator 产生的顺序对 List 集合元素进行排序 |
| public static void swap(List<?> list,int i,int j) | 将指定 list 集合中的 i 处元素和 j 处元素进行交换 |
| public static int frequency(Collection<?> c,Object o) | 返回指定集合中指定元素的出现次数 |
| public static <T> void copy(List<? super T> dest,List<? extends T> src) | 将src中的内容复制到dest中 |
| public static <T> boolean replaceAll(List<T> list,T oldVal,T newVal) | 使用新值替换 List 对象的所有旧值 |
| synchronizedXxx() | 该方法可使将指定集合包装成线程同步的集合,从而可以解决多线程并发访问集合时的线程安全问题 |
| unmodifiableXxx() | 该方法返回指定 Xxx的不可修改的视图。 |
更多推荐

所有评论(0)