Map集合

Map集合概述

Map是java.util包中的接口。

Map集合特点:该集合存储键值对。一对一对的往里存。而且要保证键的唯一性。Map接口中的方法如下:

1.添加

put(K Key,V value)

putAll(Map<? extends K,? extends V> m)

2.删除

clear()

remove(Object key)

3.判断

containsValue(Object value)

containsKey(Object key)

isEmpty()

4.获取

get(Object key):根据键获取值

size()

values():获取所有值的Collection集合

entrySet()

keySet()


Map的子类

|——Hashtable:底层是哈希表数据结构,不可以存入null键null值。该集合是线程同步的。jdk1.0.效率低

|——HashMap:底层是哈希表数据结构,可以存入null键和null值,该集合是不同步的。jdk1.2效率高

|——TreeMap:底层是二叉树数据结构。线程不同步。可以用于给Map集合中的键排序。

Set集合底层用了Map集合

Map集合方法演示

下面分别演示Map集合中的方法:

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

public class MapDemo {
	public static void main(String[] args) {
		Map<String,String> map=new HashMap<String, String>();
		map.put("01", "beijing");
		map.put("02", "shanghai");
		map.put("03", "guangzhou");
		map.put("04", "shenzhen");
		System.out.println(map);
		
		String method="values()";
		switch (method) {
		case "put(K Key,V value)":
			//如果键相同,则新值覆盖旧值,返回旧值
			System.out.println(map.put("02", "haerbin"));
			System.out.println(map);
			//如果键不同,则添加新键值对,返回null
			System.out.println(map.put("05", "haerbin"));
			System.out.println(map);
			//null也可以作为键或值存入HashMap集合
			map.put(null, null);
			System.out.println(map);
			break;
		case "putAll(Map<? extends K,? extends V> m)":
			Map<String,String> map2=new HashMap<String, String>();
			map2.put("03", "beijing");
			map2.put("05", "shanghai");
			map.putAll(map2);
			System.out.println(map);
			break;
		case "clear()":
			map.clear();
			System.out.println(map);
			break;
		case "remove(Object key)":
			//remove方法删除键值对,并返回值
			System.out.println(map.remove("03"));
			System.out.println(map);
			//如果指定的键不存在,则返回null
			System.out.println(map.remove("05"));
			break;
		case "containsKey(Object key)":
			System.out.println(map.containsKey("01"));
			break;
		case "containsValue(Object key)":
			System.out.println(map.containsValue("guangzhou"));
			break;
		case "isEmpty()":
			System.out.println(map.isEmpty());
			map.clear();
			System.out.println(map.isEmpty());
			break;
		case "get(Object key)":
			System.out.println(map.get("01"));
			map.put(null, "NewYork");
			//get方法也可以判断键为null的值
			System.out.println(map.get(null));
			//如果指定的键对应的值不存在或为null,则返回null
			System.out.println(map.get("05"));
			break;
		case "size()":
			System.out.println(map.size());
			break;
		case "values()":
			Collection<String> col=map.values();
			System.out.println(col);
			break;
		default:
			break;
		}
	}
}

学习完本节后,已经学习了1个接口(Map),10个方法。类图如下:


Map集合取出键值对

map集合中两种取出所有键值对的方法

1,keySet:返回Set<K>将map中所有的键存入到Set集合。因为Set具备迭代器。所以可以用迭代的方式取出所有键,然后根据get方法。获取每一个键对应的值。

2,entrySet:返回Set<Map.Entry<K,V>>

第一种方式演示代码如下:

	public static void demo2(){
		Map<String, String> map=new HashMap<String, String>();
		map.put("01", "beijing");
		map.put("02", "shanghai");
		map.put("03", "guangzhou");
		map.put("04", "shenzhen");
		
		Set<String> set=map.keySet();
		Iterator<String> it=set.iterator();
		while(it.hasNext()){
			String key=it.next();
			//通过map集合get方法取出元素值
			System.out.println("key:"+key+" value:"+map.get(key));
		}
	}
第二种方式获取键值对演示如下:

	public static void demo3(){
		Map<String, String> map=new HashMap<String, String>();
		map.put("01", "beijing");
		map.put("02", "shanghai");
		map.put("03", "guangzhou");
		map.put("04", "shenzhen");
		
		Set<Map.Entry<String, String>> set=map.entrySet();
		Iterator<Map.Entry<String, String>> it=set.iterator();
		while (it.hasNext()) {
			Map.Entry<String, String> entry =it.next();
			String key=entry.getKey();
			String value=entry.getValue();
			System.out.println(key+":"+value);
		}
	}
下面解释Map.Entry:

interface Map{
	public static interface Entry{
		public abstract Object getKey();
		public abstract Object getValue();
	}
}
class HashMap implements Map{
	class MapEntry implements Map.Entry{
		public Object getKey(){}
		public Object getValue(){}
	}
}

Entry接口是Map接口的内部接口,所以才会有Map.Entry接口这种奇怪的写法。Map.Entry在使用时,可以将点看做接口名的一部分,而不必在意实现的具体细节。

本节学习了1个接口(Map.Entry)4个方法。本章到目前共学习2个接口,14个方法,如下图所示:


HashMap

HashMap类似HashSet,不同之处在与HashMap是双列集合,HashSet是单列集合。HashMap同HashSet一样都是通过hashCode方法和equals方法来保证键的唯一性。

每一个学成都有对应的归属地。学生Student,地址String。学生属性:姓名、年龄、姓名和年龄相同视为同一个学生。保证学生唯一性。

1.描述学生

2.定义map容器。将学生作为键,地址作为值。存入。

3.获取map集合中的元素

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

class People{
	int age;
	String name;
	@Override
	public String toString() {
		return "People [age=" + age + ", name=" + name + "]";
	}
	@Override
	public int hashCode() {
		return age*31 + ((name == null) ? 0 : name.hashCode());
	}
	@Override
	public boolean equals(Object obj) {
		if (!(obj instanceof People)) {
			throw new ClassCastException("被比较的类不是People类");
		}
		People people=(People)obj;
		if (people.getAge()==age&&people.getName().equals(name)) {
			return true;
		}
		return false;
	}
	public People(int age, String name) {
		super();
		this.age = age;
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public String getName() {
		return name;
	}
}

public class HashMapDemo {
	public static void main(String[] args) {
		HashMap<People,String> hm=new HashMap<People,String>();
		hm.put(new People(21,"lisi01"), "jiangsu");
		hm.put(new People(23,"lisi02"), "jiangxi");
		hm.put(new People(23,"lisi02"), "fujian");
		hm.put(new People(41,"lisi03"), "shanxi");
		//第一种遍历方式
		Set<People> set=hm.keySet();
		Iterator<People> it=set.iterator();
		while (it.hasNext()) {
			People people = it.next();
			System.out.println(people+" "+hm.get(people));
		}
		//第二种遍历方式
		Set<Map.Entry<People,String>> entry=hm.entrySet();
		
		Iterator<Map.Entry<People,String>> it1=entry.iterator();
		while (it1.hasNext()) {
			Map.Entry<People, String> entry2 = it1.next();
			System.out.println(entry2.getKey()+" "+entry2.getValue());
		}
	}
}
上面的代码演示了HashMap类的用法。Map集合类图如下:

TreeMap

TreeMap类似TreeSet,可以给存入其中的键值对按键排序,可以以两种方式自定义排序,一种是键对象实现comparable接口,一种是创建TreeMap对象时给构造方法传入一个比较器(实现comparator接口的类)。

下面对People类进行改造,使之具有按姓名和年龄排序的自然顺序。

class People implements Comparable<People>{
	int age;
	String name;
	@Override
	public String toString() {
		return "People [age=" + age + ", name=" + name + "]";
	}
	@Override
	public int hashCode() {
		return age*31 + ((name == null) ? 0 : name.hashCode());
	}
	@Override
	public boolean equals(Object obj) {
		if (!(obj instanceof People)) {
			throw new ClassCastException("被比较的类不是People类");
		}
		People people=(People)obj;
		if (people.getAge()==age&&people.getName().equals(name)) {
			return true;
		}
		return false;
	}
	public People(int age, String name) {
		super();
		this.age = age;
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public String getName() {
		return name;
	}
	@Override
	public int compareTo(People o) {
		int num=new Integer(age).compareTo(new Integer(o.getAge()));
		if (num==0) {
			return name.compareTo(o.name);
		}
		return num;
	}
}

上面的代码注意Comparable接口带泛型的用法

然后写一个主函数测试下:

import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

public class TreeMapDemo {
	public static void main(String[] args) {
		TreeMap<People,String> hm=new TreeMap<People,String>();
		hm.put(new People(21,"lisi01"), "jiangsu");
		hm.put(new People(23,"lisi02"), "jiangxi");
		hm.put(new People(23,"lisi01"), "fujian");
		hm.put(new People(25,"lisi03"), "shanxi");

		Set<Map.Entry<People,String>> entry=hm.entrySet();
		
		Iterator<Map.Entry<People,String>> it1=entry.iterator();
		while (it1.hasNext()) {
			Map.Entry<People, String> entry2 = it1.next();
			System.out.println(entry2.getKey()+" "+entry2.getValue());
		}
	}
}
打印结果:

People [age=21, name=lisi01] jiangsu
People [age=23, name=lisi01] fujian
People [age=23, name=lisi02] jiangxi
People [age=25, name=lisi03] shanxi

注意到,People对象先按年龄排序,然后按姓名排序,这点事根HashMap不一样的地方。


下面用比较器的方法指定顺序:(先按姓名排序,再按年龄排序)

import java.util.Comparator;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

class PeopleNameComparator implements Comparator<People>{

	@Override
	public int compare(People o1, People o2) {
		int num=o1.getName().compareTo(o2.getName());
		if (num==0) {
			return new Integer(o1.getAge()).compareTo(new Integer(o2.getAge()));
		}
		return num;
	}
	
}

public class TreeMapDemo {
	public static void main(String[] args) {
		TreeMap<People,String> hm=new TreeMap<People,String>(new PeopleNameComparator());
		hm.put(new People(21,"java03"), "jiangsu");
		hm.put(new People(24,"java01"), "jiangxi");
		hm.put(new People(23,"java07"), "fujian");
		hm.put(new People(25,"java02"), "shanxi");

		Set<Map.Entry<People,String>> entry=hm.entrySet();
		
		Iterator<Map.Entry<People,String>> it1=entry.iterator();
		while (it1.hasNext()) {
			Map.Entry<People, String> entry2 = it1.next();
			System.out.println(entry2.getKey()+" "+entry2.getValue());
		}
	}
}
运行结果:

People [age=24, name=java01] jiangxi
People [age=25, name=java02] shanxi
People [age=21, name=java03] jiangsu
People [age=23, name=java07] fujian
上面的代码,注意Comparator带泛型的用法。

到这里共学习2个类,2个接口,14个方法。类图见下面:

TreeMap练习

“ a;sdkfja;ksdjfpiajewporfikj;adkjnvfa;skeirjf"获取该字符串中字母出现的次数。

希望打印结果:a(1)c(2)....

通过结果发现,每一个字母都有对应的次数。

说明字母和次数之间有映射关系。于是使用Map集合。

当数据之间存在映射关系时,就要首先想到Map集合。

思路:

1.将字符串转换成字符数组。因为要对每一个字母进行操作。

2.定义一个Map集合,因为打印结构的字母有顺序,所以使用TreeMap集合

3.遍历字符数组。

将每一个字母作为键取查Map集合

如果返回null,将该字母和1存入Map集合中。

如果返回不是null,说明该字母在Map集合中已经存在并有对应次数。

那么就获取该字数自增。然后将该字母和自增后的次数存入Map集合中。覆盖掉原来键对应的值

4.将Map集合中的数据编程指定的字符串格式返回。

代码如下:

import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

public class TreeMapDemo2 {
	public static void main(String[] args) {
		System.out.println(getCharCount("asdffasdfj;akjewo[hfaeswdf"));
	}
	public static String getCharCount(String str){
		StringBuilder sb=new StringBuilder();
		
		TreeMap<Character,Integer> tree=new TreeMap<Character,Integer>();
		
		char[] chars=str.toCharArray();
		for (int i = 0; i < chars.length; i++) {
			if (chars[i]>='a'&&chars[i]<='z') {
				Integer value=tree.get(chars[i]);
				tree.put(chars[i],value==null?1:++value);
			}	
		}
		
		Set<Map.Entry<Character, Integer>> set=tree.entrySet();
		
		Iterator<Map.Entry<Character, Integer>> it=set.iterator();
		while (it.hasNext()) {
			Map.Entry<Character, Integer> entry = (Map.Entry<Character, Integer>) it.next();
			sb.append(entry.getKey()+"("+entry.getValue()+")");
		}
		
		return sb.toString();
	}
}

嵌套集合

现有以下数据:

“预热班”   “01”   “张三”

“预热班”   “02”    “李四”

“就业班”     “01”   “王五”

“赵六”     “02”     “赵六”

请用嵌套集合保存数据,并打印:

Map集合与List集合嵌套,代码如下

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

class Trainer{
	int stuNo;
	String name;
	public Trainer(int stuNo, String name) {
		this.stuNo = stuNo;
		this.name = name;
	}
	public int getStuNo() {
		return stuNo;
	}
	public String getName() {
		return name;
	}
}

public class NestedList {
	public static void main(String[] args) {
		//<班级名,学生集合>
		Map<String,List<Trainer>> school=new HashMap<String,List<Trainer>>();
		
		List<Trainer> students1=new ArrayList<Trainer>();
		students1.add(new Trainer(01, "张三"));
		students1.add(new Trainer(02, "李四"));
		
		List<Trainer> students2=new ArrayList<Trainer>();
		students2.add(new Trainer(01, "王五"));
		students2.add(new Trainer(02, "赵六"));
		
		school.put("预热班", students1);
		school.put("就业班", students2);
		//打印数据
		Set<Map.Entry<String,List<Trainer>>> set=school.entrySet();	
		Iterator<Map.Entry<String,List<Trainer>>> it=set.iterator();
		while(it.hasNext()){
			Map.Entry<String,List<Trainer>> entry=it.next();
			System.out.println(entry.getKey());
			List<Trainer> trainers=entry.getValue();
			Iterator<Trainer> iter=trainers.iterator();
			while (iter.hasNext()) {
				Trainer trainer =iter.next();
				System.out.println(trainer.getStuNo()+" "+trainer.getName());
			}
		}
	}
}

Map集合与Map集合嵌套,代码如下

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

public class NestedMap {
		public static void main(String[] args) {
			//<班级名,学生集合>
			Map<String,Map<Integer,String>> school=new HashMap<String,Map<Integer,String>>();
			
			Map<Integer,String> students1=new HashMap<Integer,String>();
			students1.put(01, "张三");
			students1.put(02, "李四");
			
			Map<Integer,String> students2=new HashMap<Integer,String>();
			students2.put(01, "王五");
			students2.put(02, "赵六");
			
			school.put("预热班", students1);
			school.put("就业班", students2);
			//打印数据
			Set<Entry<String, Map<Integer, String>>> set=school.entrySet();	
			Iterator<Entry<String, Map<Integer, String>>> it=set.iterator();
			while(it.hasNext()){
				Entry<String, Map<Integer, String>> entry=it.next();
				System.out.println(entry.getKey());
				Map<Integer, String> trainers=entry.getValue();
				Iterator<Entry<Integer, String>> iter=trainers.entrySet().iterator();
				while (iter.hasNext()) {
					Entry<Integer, String> trainer =iter.next();
					System.out.println(trainer.getKey()+" "+trainer.getValue());
				}
			}
		}
}






你可能感兴趣的:(Map集合)