`
i学霸
  • 浏览: 12689 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

I学霸官方免费教程三十三:Java集合框架之Map集合

 
阅读更多

Map接口

Map集合采用键值对(key-value)的方式存储数据,其中键不可以重复、值可以重复。
常用类有HashMap、TreeMap和Properties

HashMap类

假如,现在我有一个集合,集合中存储着一批WiFi的名称和密码,现在要求通过名称快速找到密码。这样的需求使用List集合实现起来非常困难,Java为我们提供了另一种形式的集合,可以很好的解决这样的问题。就是Map集合。
实例:
package map.hashMap;
import java.util.HashMap;
import java.util.Map;
/**
 * 演示HashSet
 * @author 学霸联盟 - 赵灿
 */
public class HashMapDemo {
	public static void main(String[] args) {
		//创建集合对象
		Map map = new HashMap();
		/*
		 * 注意:map集合添加元素的方法是put,不是add
		 * 前一个参数代表key(键),后一个参数代表value(值)
		 */
		map.put("wifiName1", "password1");
		/*
		 * 当出现key重复时,后面的值会将前面的值覆盖
		 * 而value重复时,无影响
		 */
		map.put("wifiName2", "password2");
		map.put("wifiName2", "password3");
		map.put("wifiName3", "password3");
		//获取集合的长度,加入4次,长度为3
		int size = map.size();
		System.out.println(size);
		//获取key为"wifiName2"的value
		String wifi2 = (String)map.get("wifiName2");
		System.out.println(wifi2);
		//两种方式转换成String都可以
		String wifi3 = map.get("wifiName3").toString();
		System.out.println(wifi3);
	}
}
运行结果:
3
password3
password3

注意:Set集合会将加入的元素存储在Map集合的key上,如果出现重复不会覆盖,保留前一个;但是Map集合中加入元素出现key相同的情况时,key不会覆盖,但是value会被后加入的value覆盖。

上面我们讲到向Set集合中添加元素时,会创建Node(节点),在节点的key中保持着当前加入的元素。在该节点中还有一个value属性,同样保存一个Object对象,只不过Set中没有使用这个value属性。而Map集合中需要存储两个值key和value,其中我们调用put方法时传入的第一个参数保存在Node对象的属性key上,传入的第二个参数就是保存在Node对象的属性value上。
由此一来,在使用key获取Map集合中对应的value时,先通过在hash表中找到key所在的Node对象,然后就返回Node对象中value的值,这样就得到了key所对应的value值了。

Map集合一些常用方法的演示
实例:
package map.hashMap;
import java.util.Collection;
import java.util.HashMap;
import java.util.Set;
/**
 * 演示HashMap类中的一些常用方法
 * @author 学霸联盟 - 赵灿
 */
public class HashMapMethodDemo {
	public static void main(String[] args) {
		//创建两个班级class1和class2
		HashMap class1 = new HashMap();
		HashMap class2 = new HashMap();
		/*
		 * 向两个班级中各添加三个学生和成绩
		 * 1班中有个叫“王五”的同学,成绩是50分
		 * 2班中也有个叫“王五”的同学,成绩是90分
		 */
		class1.put("张三", "80分");
		class1.put("李四", "60分");
		class1.put("王五", "50分");
		
		class2.put("赵四", "80分");
		class2.put("陈六", "0分");
		class2.put("王五", "90分");
		//判断1班有没有姓名叫“王五”的同学
		boolean containsKey = class1.containsKey("王五");
		System.out.println("集合class1中有没有key是王五:" + containsKey);
		System.out.println("-------------------------------------");
		//判断1班有没有成绩是90分的同学
		boolean containsValue = class1.containsValue("90分");
		System.out.println("集合class1中有没有value是90分:" + containsValue);
		System.out.println("-------------------------------------");
		//将2班同学合并到一班
		class1.putAll(class2);
		//获取班级人数(集合长度)
		int size = class1.size();
		System.out.println("合并后的班级总人数:" + size);
		System.out.println("-------------------------------------");
		//获取1班所有同学的姓名
		Set nameSet = class1.keySet();
		//增强for循环输出所有姓名
		for (Object o : nameSet) {
			System.out.print(o + "  ");
		}
		System.out.println();
		System.out.println("-------------------------------------");
		//获取1班所有同学的成绩
		Collection scores = class1.values();
		//增强for循环输出所有成绩
		for (Object o : scores) {
			System.out.print(o + "  ");
		}
		System.out.println();
		System.out.println("-------------------------------------");
		//获取1班所有同学的姓名和成绩
		Set nameAndScoreSet = class1.entrySet();
		//增强for循环输出所有成绩
		for (Object o : nameAndScoreSet) {
			System.out.print(o + "  ");
		}
		System.out.println();
		System.out.println("-------------------------------------");
		//获取王五的成绩
		Object wangwuScore = class1.get("王五");
		System.out.println("合并后王五的成绩:" + wangwuScore);
		System.out.println("-------------------------------------");
		//删除key为“王五”的value
		class1.remove("王五");
		//删除“王五”后
		System.out.println("王五的成绩:" + class1.get("王五"));
		System.out.println("是否包含叫“王五”的key:" + class1.containsKey("王五"));
		System.out.println("是否包含“90分”的value:" + class1.containsValue("90分"));
		System.out.println("-------------------------------------");
		//替换陈六的成绩
		class1.replace("陈六", "59分");
		System.out.println("替换后陈六的成绩:" + class1.get("陈六"));
		System.out.println("-------------------------------------");
		//清空集合
		class1.clear();
		//判断集合是否为空
		System.out.println("用clear方法清除后集合是否为空:" + class1.isEmpty());
	}
}

总结:

Map以键值对的结构存储;
key出现重复时,新加入的key不会覆盖原key,但新加入的value会覆盖原key对应的value
key和value都可以使用null

特殊说明:其实Set集合就是将元素存储到Map的键上。创建HashSet对象A时,会底层会创建一个HashMap的对象map,当想Set集合A中添加元素时(A.add("abc")),此时会调用map.put("abc", obj);
所以Set的实现方式就是Map中key的实现方式(数组 + 单项链表),由于元素存储数组的下标由特定的hash算法获得,所以也称为散列存储
以下是HashSet中的源码
//创建HashSet对象是会在底层创建一个HashMap对象
public HashSet() {
map = new HashMap<>();
}
//向Set集合中添加元素时,底层是将添加的元素添加到map集合的key上
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}

TreeMap类

由名称可知,其key和TreeSet一样;其他属性同HashMap。所以这里不再详细讲述。
实例:
package map.treeMap;
import java.util.Set;
import java.util.TreeMap;
/**
 * 演示TreeSet集合
 * @author 学霸联盟 - 赵灿
 */
public class TreeMapDemo {
	public static void main(String[] args) {
		//创建三个树枝对象
		Branch b1 = new Branch(10);
		Branch b2 = new Branch(5);
		Branch b3 = new Branch(8);
		//创建TreeMap对象
		TreeMap tm = new TreeMap();
		tm.put(b1, "树枝10");
		tm.put(b2, "树枝5");
		tm.put(b3, "树枝8");
		//获取TreeMap中包含所有的key的集合
		Set ts = tm.keySet();
		//循环输出key
		for(Object o : ts){
			Branch b = (Branch)o;
			//输出年轮
			System.out.print("年轮:" + b.getAnnualRing());
			//根据有序的key,获取有序的value
			System.out.println("  对应的value:" + tm.get(b));
		}
	}
}

/**
 * 树枝类Branch
 * 加入TreeSet集合的元素类型必须实现Comparable接口
 * 否则程序运行的时候会出现异常
 * @author 学霸联盟 - 赵灿
 */
class Branch implements Comparable{
	//年轮:用于排序的依据
	private int annualRing;
	//带参构造方法
	public Branch(int annualRing){
		this.annualRing = annualRing;
	}
	//重写接口中的方法
	@Override
	public int compareTo(Object o) {
		//强制类型转换
		Branch b = (Branch)o;
		/*
		 * 使用年轮作为排序比较的依据
		 * 当前对象年轮减去参数传入的Branch对象的年龄
		 * 结果等于0表示:两个树枝年轮相等,排序不分先后
		 * 结果大于0表示:当前对象的年轮大,排在后面
		 * 结果小于0表示:参数对象的年轮大,排在后面
		 */
		int result = this.annualRing - b.annualRing;
		return result;
	}
	//获取年轮
	public int getAnnualRing(){
		return annualRing;
	}
}
运行结果
年轮:5  对应的value:树枝5
年轮:8  对应的value:树枝8
年轮:10  对应的value:树枝10

Properties类

从文件中获取键值对
文件内容格式
key = value
实例:
文件名:properties.txt
文件内容:
username = admin
password = 123456
文件地址:src/map/properties/properties.txt
其中文件地址是从项目根目录开始的
实例:
package map.properties;
import java.io.FileInputStream;
import java.util.Properties;
/**
 * 演示Properties类中的一些常用方法
 * @author 学霸联盟 - 赵灿
 */
public class PropertiesDemo {
	public static void main(String[] args) {
		//创建Properties对象
		Properties p = new Properties();
		/*
		 * 以下代码暂时先知道是什么作用即可,后面会讲解
		 * try - catch语句的作用是捕获异常
		 * load方法的作用是加载文件
		 * 其中的参数是文件的地址
		 */
		try {
			p.load(new FileInputStream("src/map/properties/properties.txt"));
		} catch (Exception e) {
			System.out.println("加载出错");
		}
		//获取文件中username对应的值
		String username = p.getProperty("username");
		System.out.println("用户名:" + username);
		//获取文件中password对应的值
		String password = p.getProperty("password");
		System.out.println("密码:" + password);
	}
}
运行结果:
用户名:admin
密码:123456


版权声明:本文为博主原创文章,未经博主允许不得转载。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics