注:本文讲述Java中的Map集合及Collections工具类

一、Map

目录

一、Map接口

1、概述

2、Map常用方法

3、Map集合的遍历

二、Map的实现类

1、Hash和Hashtable

2、LinkedHashMap

3、TreeMap

三、Collections工具类


接口

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的不可修改的视图。
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐