深度强化——Java中Map集合的详细用法(HashMap、TreeMap、Properties)(简述、方法、遍历..........)


Map集合先知道:


前面详细的介绍了Collectin接口以及其子接口和实用类的具体实现方法,今天再次通过 ”图文结合“ 的方法来介绍Map集合的详细使用。Map集合用于储存元素对,Map储存的是一对键值(key和value),是通过key映射到它的value。

说明:Map接口是一种双列集合,它的每个元素都包含一个键对象Key和值对象Value,
键和值对象之间存在一种对应关系,称为映射。

特点:Map中的映射关系是一对一的,一个键对象Key对应唯一一个值对象Value,
其中键对象Key和值对象Value可以是任意数据类型,并且键对象Key不允许重复,
这样在访问Map集合中的元素时,只要指定了Key,就能找到对应的Value。


Map集合中常用的方法:



HashMap:


说明:HashMap集合是Map接口的一个实现类,它用于存储键值映射关系,
该集合的键和值允许为空,但键不能重复,且集合中的元素是无序的。
特点:HashMap底层是由哈希表结构组成的,其实就是“数组+链表”的组合体,
数组是HashMap的主体结构,链表则主要是为了解决哈希值冲突而存在的分支结构。
正因为这样特殊的存储结构,HashMap集合对于元素的增、删、改、查操作表现出的效率都比较高。

HashMap内部结构

HashMap集合存储原理

在哈希表结构中,主体结构为图中水平方向的数组结构,其长度称为HashMap集合的容量(capacity);
数组结构垂直对应的是链表结构,链表结构称为一个桶(bucket),
每个桶的位置在集合中都有对应的桶值,用于快速定位集合元素添加、查找时的位置。

HashMap接口小提示:

HashMap的使用:

Map集合的遍历:

Iterator迭代器遍历Map集合——keySet()方法

遍历思路:先将Map集合中所有键对象转换为Set单列集合,
接着将包含键对象的Set集合转换为Iterator接口对象,
然后遍历Map集合中所有的键,再根据键获取相应的值。

Iterator迭代器遍历Map集合——entrySet()方法

遍历思路:将原有Map集合中的键值对作为一个整体返回为Set集合,
接着将包含键值对对象的Set集合转换为Iterator接口对象,
然后获取集合中的所有的键值对映射关系,再从映射关系中取出键和值。 
Map集合值遍历——values()方法


说明:在Map集合中,除了以上介绍的两种主要的遍历方式外,
还提供了一个values()方法,通过这个方法可以直接获取Map中存储所有值的Collection集合。 

在这里插入图片描述

JDK 8新方法遍历Map集合


说明:在JDK 8中,根据Lambda表达式特性新增了一个forEach(BiConsumer action)方法来遍历Map集合,
该方法所需要的参数也是一个函数式接口,
因此可以使用Lambda表达式的书写形式来进行集合遍历。 

在这里插入图片描述

代码描述:
package jiHe;

import java.util.*;

public class MapDomo {
  public static void main(String[] args) {
   Map m = new HashMap();
   m.put(1, "aa");
   m.put(3, "gg");
   m.put(7, "kk");
   m.put(3, "古德");
   m.put(2, "pp");
   m.put(2, "qq");//键重复的时候,值直接被重写(覆盖)
   System.out.println(m);//结果看着是排序的,其实不是,是无序的
   System.out.println("1================================");
   //====================
   System.out.println(m.get(7));//键值
   System.out.println(m.remove(1));//若找不到键为1的就返回NULL
   System.out.println(m.size());
   System.out.println(m.containsKey(6));
   System.out.println(m.containsValue("pp"));
   System.out.println(m.containsValue("qq"));
   System.out.println(m);
   System.out.println("2================================");
   //==============================
   //返回你给出键的值,若没有找到你所给出的键,那么久返回你给的键所对应你给出的值
   System.out.println(m.getOrDefault(3 , "kkk"));
   System.out.println(m.getOrDefault(4, "kkk"));
   System.out.println("3=================================");
   //============================
   //遍历思路:先将Map集合中所有键对象转换为Set单列集合,接着将包含键对象的Set集合转换为Iterator接口对象
   //然后遍历Map集合中所有的键,再根据键获取相应的值。
   Set s = m.keySet();
   System.out.println(s);


   Iterator it = s.iterator();
   while(it.hasNext()) {
    Object key = it.next();//通过it.next()方法获得的都是Object类型的对象
    Object value = m.get(key);//通过get()方法获得的都是Object类型的对象
    //推荐上面的两条语句转换为下面的两条强转的语句
    //Integer key1 = (Integer)it.next();
    //String value1 = (String)m.get(key1);
    System.out.println(key+"   "+value);
   }
   System.out.println("4======================================");
   //=======================================
//   遍历思路:将原有Map集合中的键值对作为一个整体返回为Set集合,接着将包含键值对对象的Set集合转换为Iterator接口对象,
//   然后获取集合中的所有的键值对映射关系,再从映射关系中取出键和值。 
   Set s2 = m.entrySet();
   Iterator it2 = s2.iterator();
   while(it2.hasNext()) {
    Map.Entry  entry = (Map.Entry)(it2.next());//强制转换(此处有点像内部类创建对象的形式)
    Object key = entry.getKey();
    Object value = entry.getValue();
    //Integer key1 = (Integer)entry.getKey();
    //String value1 = (String)entry.getValue();
    System.out.println(key+"   "+value);
    }
   System.out.println("5==========================================");
   //=========================================
//   在JDK 8中,根据Lambda表达式特性新增了一个forEach(BiConsumer action)方法来遍历Map集合,
//   该方法所需要的参数也是一个函数式接口,因此可以使用Lambda表达式的书写形式来进行集合遍历。 
   m.forEach((ke,value)->System.out.println(ke+" : "+value));
   System.out.println("6===========================================");
   //====================================
   Collection  value = m.values();//只获取值的方法
   value.forEach(v->System.out.println(v));//v---形参
  }
}

完善代码:

package jiCheng_duoTai;

import java.util.*;
import java.util.Map.Entry;

public class MapDomo {
	public static void main(String[] args) {
		Map<Integer, String> m = new HashMap<Integer, String>();
		m.put(1, "aa");
		m.put(3, "gg");
		m.put(7, "kk");
		m.put(3, "古德");
		m.put(2, "pp");
		m.put(2, "qq");// 键重复的时候,值直接被重写(覆盖)
		System.out.println(m);// 结果看着是排序的,其实不是,是无序的
		System.out.println("1================================");
		// ====================
		System.out.println(m.get(7));// 键值
		System.out.println(m.remove(1));// 若找不到键为1的就返回NULL
		System.out.println(m.size());
		System.out.println(m.containsKey(6));
		System.out.println(m.containsValue("pp"));
		System.out.println(m.containsValue("qq"));
		System.out.println(m);
		System.out.println("2================================");
		// ==============================
		// 返回你给出键的值,若没有找到你所给出的键,那么久返回你给的键所对应你给出的值
		System.out.println(m.getOrDefault(3, "kkk"));
		System.out.println(m.getOrDefault(4, "kkk"));
		System.out.println("3=================================");
		// ============================
		// 遍历思路:先将Map集合中所有键对象转换为Set单列集合,接着将包含键对象的Set集合转换为Iterator接口对象
		// 然后遍历Map集合中所有的键,再根据键获取相应的值。
		Set<Integer> s = m.keySet();
		System.out.println(s);

		Iterator<Integer> it = s.iterator();
		while (it.hasNext()) {
			Object key = it.next();// 通过it.next()方法获得的都是Object类型的对象
			Object value = m.get(key);// 通过get()方法获得的都是Object类型的对象
			// 推荐上面的两条语句转换为下面的两条强转的语句
			// Integer key1 = (Integer)it.next();
			// String value1 = (String)m.get(key1);
			System.out.println(key + "   " + value);
		}
		System.out.println("4======================================");
		// =======================================
//   遍历思路:将原有Map集合中的键值对作为一个整体返回为Set集合,接着将包含键值对对象的Set集合转换为Iterator接口对象,
//   然后获取集合中的所有的键值对映射关系,再从映射关系中取出键和值。 
		Set<Map.Entry<Integer, String>> s2 = m.entrySet();
		Iterator<Entry<Integer, String>> it2 = s2.iterator();
		while (it2.hasNext()) {
			Map.Entry<Integer, String> entry = (Map.Entry<Integer, String>) (it2.next());// 强制转换(此处有点像内部类创建对象的形式)
			Object key = entry.getKey();
			Object value = entry.getValue();
			// Integer key1 = (Integer)entry.getKey();
			// String value1 = (String)entry.getValue();
			System.out.println(key + "   " + value);
		}
		System.out.println("5==========================================");
		// =========================================
//   在JDK 8中,根据Lambda表达式特性新增了一个forEach(BiConsumer action)方法来遍历Map集合,
//   该方法所需要的参数也是一个函数式接口,因此可以使用Lambda表达式的书写形式来进行集合遍历。 
		m.forEach((ke, value) -> System.out.println(ke + " : " + value));
		System.out.println("6===========================================");
		// ====================================
		Collection<String> value = m.values();// 只获取值的方法
		value.forEach(v -> System.out.println(v));// v---形参
	}
}

TreeMap


介绍: TreeMap集合是Map接口的另一个实现类,
在TreeMap内部是通过二叉树的原理来保证键的唯一性,这与TreeSet集合存储的原理一样,因此TreeMap中所有的键是按照某种顺序排列的。
说明:为了实现TreeMap元素排序,可以参考TreeSet 集合排序方式,使用自然排序和定制排序。

首先创建了一个TreeMap集合,并使用put()方法按顺序向集合中添加了3个元素,然后打印出集合信息。
从运行结果可以看出,取出的元素按照键对象的自然顺序进行了排序,
这是因为添加的元素中键对象是String类型,String类实现了Comparable接口,
因此默认会按照自然顺序对元素进行排序。
同TreeSet集合-样,在使用TreeMap集合时,也可以通过自定义比较器Comparator的方式对所有的键进行定制排序。
接下来将集合中的元素按照键对象由大到小进行排序
package jiHe;

import java.util.*;

//可以排序
public class TreeMapDomo {
  public static void main(String[] args) {
   TreeMap tm = new TreeMap();
   tm.put(3, "java");
   tm.put(2, "C");
   tm.put(5, "C++");
   tm.put(1, "Wab");
   System.out.println(tm);
   System.out.println("1============================");
   tm.put(1, "Wab");//重复的不会再添加进来
   tm.put(1, "Wabss");//覆盖
   System.out.println(tm);//实现了Comparable接口,该接口有一个compareTo方法
   System.out.println("2=============================");
   //怎么希望降序排序?而不再是升序排序
   //自定义,定制排序
   //注意,Integer不能强制转换为String,可以通过调用方法进行转换
   TreeMap tm2 = new TreeMap(new Mycompare());
   tm2.put("3","java");
   tm2.put("2","C");
   tm2.put("5","C++");
   tm2.put("1","Wab");
   System.out.println(tm2);
  }
}
class Mycompare implements Comparator{
 public int compare(Object a,Object b) {
  String s1 = (String)a;
  String s2 = (String)b;
  return s2.compareTo(s1);
  //  return -Integer.parseInt(s1)+Integer.parseInt(s2);
 }
}

在这里插入图片描述

上面代码改写:

package jiCheng_duoTai;

import java.util.*;

//可以排序
public class TreeMapDomo {
	public static void main(String[] args) {
		TreeMap<Integer, String> tm = new TreeMap<Integer, String>();
		tm.put(3, "java");
		tm.put(2, "C");
		tm.put(5, "C++");
		tm.put(1, "Wab");
		System.out.println(tm);
		System.out.println("1============================");
		tm.put(1, "Wab");// 重复的不会再添加进来
		tm.put(1, "Wabss");// 覆盖
		System.out.println(tm);// 实现了Comparable接口,该接口有一个compareTo方法
		System.out.println("2=============================");
		// 怎么希望降序排序?而不再是升序排序
		// 自定义,定制排序
		// 注意,Integer不能强制转换为String,可以通过调用方法进行转换
		TreeMap<Integer, String> tm2 = new TreeMap<Integer, String>(new Mycompare());
		tm2.put(3, "java");
		tm2.put(2, "C");
		tm2.put(5, "C++");
		tm2.put(1, "Wab");
		System.out.println(tm2);
	}
}

class Mycompare implements Comparator<Object> {
	public int compare(Object a, Object b) {
		Integer s1 =  (Integer) a;
		Integer s2 =  (Integer) b;
		return  s2-s1;
	}
}

在这里插入图片描述


Properties集合


介绍: Map接口还有一个实现类Hashtable,它和HashMap十分相似,其中一个主要区别在于Hashtable是线程安全的。

说明:Hashtable类有一个子类Properties。Properties主要用来存储字符串类型的键和值,在实际开发中,经常使用Properties集合类来存取应用的配置项。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱睡觉的小馨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值