其他分享
首页 > 其他分享> > 四十、Map集合

四十、Map集合

作者:互联网

1、概述

java.util.Map<K,V> 集合,里面保存的数据是成对存在的,称之为双列集合。存储的数据,我们称为键值对。 之前所学的Collection集合中元素单个单个存在的,称为单列集合。

K:键的数据类型;V:值的数据类型

  1. 键不能重复,值可以重复
  2. 键和值是一一对应的,通过键可以找到对应的值
  3. (键 + 值)一起是一个整体,我们称之为 “键值对” 或者 “键值对对象” ,在Java中叫做 “Entry对象”

2、Map实现类

HashMap:

此前的HashSet底层实现就是HashMap完成的,HashSet保存的元素其实就是HashMap集合中保存的键,底层结构是哈希表结构,具有键唯一,无序,特点。

LinkedHashMap:

底层结构是有链表和哈希表结构,去重,有序

TreeMap:

底层是有红黑树,去重,通过键进行排序

3、Map中常用方法

方法 描述
public V put(K key, V value) 把指定的键与指定的值添加到Map集合中。也可以做修改操作
public V remove(Object key) 把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的值。
public V get(Object key) 根据指定的键,在Map集合中获取对应的值。
public Set<K> keySet() 获取Map集合中所有的键,存储到 Set 集合中。
Collection<V> values() 获取Map集合中所有的值,存储到 Collection 集合中。
public Set<Map.Entry<K,V>> entrySet() 获取到Map集合中所有的键值对对象的集合(Set集合)。
public boolean containKey(Object key) 判断该集合中是否有此 key 键。
public boolean containValue(Object value) 判断该集合中是否有此 value 值。

4、Map集合遍历

Map集合既不能使用索引来遍历,也不能使用迭代器遍历,如果要进行对Map集合遍历,可以有两种方式:

遍历一:键找值方式

操作步骤:

  1. 获取Map中所有的键,由于键是唯一的,所以返回一个Set集合存储所有的键。方法提示:keyset()
  2. 遍历键的Set集合,得到每一个键。
  3. 根据键,获取键所对应的值。方法提示:get(K key)

遍历图解:

遍历二:键值对对象遍历

即通过集合中每个键值对(Entry)对象,获取键值对(Entry)对象中的键与值

操作步骤:

  1. 获取Map结合中,所有的键值对(Entry)对象,以Set集合形式返回。使用方法entrySet()

    public Set<Map.Entry<K,V>> entrySet()

  2. 遍历包含键值对(Entry)对象的Set集合,得到每一个键值对(Entry)对象

  3. 通过键值对(Entry)对象,获取Entry对象中的键与值。使用方法getKey() getValue()

    public K getKey()

    public V getValue()

遍历图解:

tips:Map集合不能直接使用迭代器或者foreach进行遍历。但是转成Set之后就可以使用了。

5、HashMap存储自定义类型

练习:每位学生(姓名,年龄)都有自己的家庭住址。那么,既然有对应关系,则将学生对象和家庭住址存储到map集合中。学生作为键, 家庭住址作为值。

【学生类】
public class Student {
    private String name;
    private int age;

    //构造方法
    //get/set
    @Override
    public boolean equals(Object o) {
        if (this == o)
            return true;
        if (o == null || getClass() != o.getClass())
            return false;
        Student student = (Student) o;
        return age == student.age && Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}

【测试类】
public class HashMapTest {
    public static void main(String[] args) {
        //1,创建Hashmap集合对象。
        Map<Student,String> map = new HashMap<Student,String>();
        //2,添加元素。
        map.put(new Student("lisi",28), "上海");
        map.put(new Student("wangwu",22), "北京");
        map.put(new Student("wangwu",22), "南京");
        
        //3,取出元素。键找值方式
        Set<Student> keySet = map.keySet();
        for(Student key: keySet){
            String value = map.get(key);
            System.out.println(key.toString()+"....."+value);
        }
    }
} 

6、LinkedHashMap

我们知道HashMap保证成对元素唯一,并且查询速度很快,可是成对元素存放进去是没有顺序的,那么我们要保证有序,还要速度快怎么办呢?

在HashMap下面有一个子类LinkedHashMap,它是链表和哈希表组合的一个数据存储结构。

代码体现:

public class LinkedHashMapDemo {
    public static void main(String[] args) {
        LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
        map.put("邓超", "孙俪");
        map.put("李晨", "范冰冰");
        map.put("刘德华", "朱丽倩");
        Set<Entry<String, String>> entrySet = map.entrySet();
        for (Entry<String, String> entry : entrySet) {
            System.out.println(entry.getKey() + "  " + entry.getValue());
        }
    }
}
/*
邓超  孙俪
李晨  范冰冰
刘德华  朱丽倩
*/

7、TreeMap集合

7.1 概述

TreeMap集合和Map相比没有特有的功能,底层的数据结构是红黑树;可以对元素的进行排序,排序方式有两种:自然排序比较器排序;到时使用的是哪种排序,取决于我们在创建对象的时候所使用的构造方法;

public TreeMap():默认使用自然排序
public TreeMap(Comparator<? super K> comparator) Comparator比较器排序

7.2 自然排序

public static void main(String[] args) {
 	TreeMap<Integer, String> map = new TreeMap<Integer, String>();
  	map.put(1,"张三");
  	map.put(4,"赵六");
  	map.put(3,"王五");
  	map.put(6,"酒八");
  	map.put(5,"老七");
  	map.put(2,"李四");
  	System.out.println(map);
}

控制台的输出结果为:
{1=张三, 2=李四, 3=王五, 4=赵六, 5=老七, 6=酒八}

7.3 比较器排序

需求:

  1. 创建一个TreeMap集合,键是学生对象(Student),值是居住地 (String)。存储多个元素,并遍历。
  2. 要求按照学生的年龄进行升序排序,如果年龄相同,比较姓名的首字母升序, 如果年龄和姓名都是相同,认为是同一个元素;

实现:

为了保证age和name相同的对象是同一个,Student类必须重写hashCode和equals方法

【Student类】
public class Student {
    private int age;
    private String name;
	//省略get/set..
    public Student() {}
    public Student(int age, String name) {
        this.age = age;
        this.name = name;
    }
    @Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age &&
                Objects.equals(name, student.name);
    }
    @Override
    public int hashCode() {
        return Objects.hash(age, name);
    }
}

【测试类】
public static void main(String[] args) {
  	TreeMap<Student, String> map = new TreeMap<Student, String>(new Comparator<Student>() {
    	@Override
    	public int compare(Student o1, Student o2) {
      		//先按照年龄升序
      		int result = o1.getAge() - o2.getAge();
      		if (result == 0) {
        		//年龄相同,则按照名字的首字母升序
        		return o1.getName().charAt(0) - o2.getName().charAt(0);
      		} else {
        		//年龄不同,直接返回结果
        		return result;
      		}
    	}
  	});
  	map.put(new Student(30, "jack"), "深圳");
  	map.put(new Student(10, "rose"), "北京");
  	map.put(new Student(20, "tom"), "上海");
  	map.put(new Student(10, "marry"), "南京");
  	map.put(new Student(30, "lucy"), "广州");
  	System.out.println(map);
}
/*
控制台的输出结果为:
{
  Student{age=10, name='marry'}=南京, 
  Student{age=10, name='rose'}=北京, 
  Student{age=20, name='tom'}=上海, 
  Student{age=30, name='jack'}=深圳, 
  Student{age=30, name='lucy'}=广州
} 
*/

标签:Map,name,map,age,四十,Student,集合,public
来源: https://www.cnblogs.com/6ovo6/p/14951655.html