Java-Map

Map集合:

java.util.Map<k,v>集合
双列结合,夫妻制,一个元素包含两个值(一个key,一个value)
map集合中的元素,key和value的数据类型可以相同,也可以不同
map集合中的元素key是不允许重复的,value是可以重复的
键值对,键不可以重复,但是值可以重复。
一个键只能对应一个值,但是一个值可以对应多个键。
map集合的元素,key和value一一对应

常用:
java.util.HashMap<k,v>集合 implements Map<k,v>接口
HashMap底层是哈希表,查询的速度特别快
jdk1.8之前:数组+单向链表
jdk1.8之后:数组+单向链表/红黑树(链表的长度超过8):提高查询的速度
hashMap集合是一个无序的集合,存储元素和取出元素的顺序可能不一致

java.util.LinkedHashMap<k,v>集合  extends HashMap<k,v>集合
	LinkedHashMap的特点:
		LinkedHashMap集合底层是哈希表+链表(保证迭代的顺序)	
		LinkedHashMap集合是一个有序的集合,,存储和取出的顺序是一致的

============================

 public class MapCls {

	public static void main(String[] args) {
		show01();
//		show02();
//		show03();
//		show04();
	}
	/*
	 * public V put (K key, V value):把指定的键与指定的值添加到集合中
	 * 		返回值:v
	 * 		  存储键值对的时候,key不重复,返回值v是null
	 * 		  存储键值对的时候,key重复,会使用新的 value 替换 map 中重复的value 返回被替换的value
	 * 	
	 */
	public static void show01(){
		//创建,多态,指向实现类,父类是一个接口,接口只能通过他的实现类来完成。
		Map<String,String> map = new HashMap<>();
		String v1 = map.put("寒冰", "蛮王");
		System.out.println(v1);//null,存储的时候key不重复,返回为null
		String v2 = map.put("寒冰", "蛮王2");
		System.out.println(v2);//返回被替换的蛮王
		//value可以重复
		map.put("杨过", "小龙女");
		map.put("引志平", "小龙女");
		System.out.println(map);
	}
	
	/*
	 * public V remove (Object key):把指定的键,所对应的键值对元素,在map集合中删除,返回被删除元素的值
	 * 		返回值:
	 * 			key存在,v返回被删除的值
	 * 			key不存在,v返回空null
	 */
	public static void show02(){
		//创建
		Map<String,Integer> map = new HashMap<>();
		map.put("迪丽热巴", 168);
		map.put("古力娜扎", 170);
		System.out.println(map);
		Integer v1 = map.remove("迪丽热巴");
		System.out.println(v1);
		//没有对应的值,返回空,上面已经删除了.
		Integer v2 = map.remove("迪丽热巴");
		System.out.println(v2);
	}
	/*
	 * public V get (Object key):根据指定的键,在Map集合中获取对应的值
	 * 		返回值:
	 * 			key存在,返回对应的value的值
	 * 			key不存在,返回null
	 * 
	 */
	public static void show03(){
		//创建Map集合对象
		Map<String,Integer> map = new HashMap<>();
		map.put("赵丽颖", 168);
		map.put("杨颖", 165);
		map.put("范冰冰", 170);
		Integer v1 = map.get("范冰冰");
		//返回对应的值
		System.out.println(v1);//170
		//没有对应的值,返回空
		Integer v2 = map.get("小龙女");
		System.out.println(v2);//
	}
	
	/*
	 * 	判断集合中的键是否存在。
	 *	boolean containsKey(Object key) 判断集合中是否包含指定的键
	 *		包含则返回true,不包含则返回false
	 * 
	 */
	public static void show04(){
		//创建集合,添加元素。
		Map<String,Integer> map = new HashMap<>();
		map.put("赵丽颖", 168);
		map.put("杨颖", 165);
		map.put("范冰冰", 170);
		boolean b1 = map.containsKey("赵丽颖");
		System.out.println(b1);
		
		boolean b2 = map.containsKey("赵颖");
		System.out.println(b2);
		
	}

}

HashMap

java.util.LinkedHashMap<K,V> extends HashMap<K,V>
Map接口的哈希表和链接列表实现具有可预知的迭代顺序,有序的集合LinkedHashMap<K,V>
底层原理:
哈希表+链表(记录元素的顺序)
因为键是唯一的但是值不是,当键冲突的时候,下面的值会替换掉上面的值,为止摆键首次出现的地方。

================================

import java.util.HashMap;
import java.util.LinkedHashMap;

public class LinkedHashMapCls {

	public static void main(String[] args) {
		HashMap<String,String> map = new HashMap<>();
		map.put("a", "a");
		map.put("c", "c");
		map.put("b", "b");
		map.put("a", "d");
		System.out.println(map);//无序的集合
		
		System.out.println("--------------------------------------");
		
		LinkedHashMap<String, String> linked = new LinkedHashMap<>();
		linked.put("a", "a");
		linked.put("c", "c");
		linked.put("b", "b");
		linked.put("a", "d");
		System.out.println(linked);//有序的集合
		
		
	}
}

集合的遍历

Map<K,V> :在map接口中有一个内部的接口Entry
当Map集合一创建,那么就会在Map集合中创建一个entry对象,用来记录键与值
(键值对对象,键与值的映射关系)–>结婚证
entrySet:把map集合内部的多个Entry对象取出来存储到一个set集合中
Set<Map.Entry<K,V>>
遍历set集合获取Set集合中每一个Entry对象
entry对象中的方法getKey()获取key
getValue()获取值

Map集合遍历的第二种方式

	使用entry进行遍历
Map集合中的方法:
	Set<Map.Entry<K,V>> entrySet() 返回此映射中包含的映射关系的Set视图
实现步骤:
		使用Map集合的方法entrySet(),把Map集合中多个entry对象取出来,存储到一个Set集合中
	 	遍历Set集合,获取每一个Entry对象
		使用Entry对象中的方法getKey()和getValue()获取键与值
把对象对应的值一个一个取出来。

================================

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

/*	
 * Map集合的第一中遍历,键找值
 *		Set<K> keySet() 返回此映射中包含的键的Set的值
 * 	 keySet遍历map集合:
 * 		把key键取出来存储到一个set集合之中,遍历set集合,获取map集合中的每一个key
 * 		然后通过这个Map集合get(key)得到key,遍历map集合
 * 
 */
public class MapKeySet {

	public static void main(String[] args) {
		Map<String,Integer> map = new HashMap<>();
		map.put("赵丽颖", 168);
		map.put("杨颖", 165);
		map.put("范冰冰", 170);
		//返回一个set集合
		Set<String> set = map.keySet();
		//使用迭代器遍历Set集合,使用迭代器,要hasNext().
		Iterator<String> it = set.iterator();
		while(it.hasNext()){
			String key = it.next();
			//通过Map集合中的方法get(key),通过key找到value
			Integer value = map.get(key);
			System.out.println(value);
		}
		System.out.println("--------------------");
		//增强for
		for (String key : set) {
			Integer value = map.get(key);
			System.out.println(key+"--"+value);
		}
		System.out.println("--------------------");
		//增强for,一步完成。map.keySet()省略了set这一步,直接完成这个操作。
		for (String key : map.keySet()) {
			Integer value = map.get(key);
			System.out.println(key+"--"+value);
		}
	}	
	
}

-----------------------------------------------------------------
 public class MapEntrySet {

	public static void main(String[] args) {
		Map<String,Integer> map = new HashMap<>();
		map.put("赵丽颖", 168);
		map.put("杨颖", 167);
		map.put("范冰冰", 170);
		//使用Map集合中的方法entrySet(),把Map集合中的多个Entry对象取出来村村到一个Set集合中
//		Set<Map.Entry<String, Integer>> set = map.entrySet();
		//使用这个方法返回的就是一个Set集合,这个集合中的内容包含一个Entry<String, Integer>
		Set<Entry<String, Integer>> set = map.entrySet();
		//遍历set集合获取每一个entry对象
		//使用迭代器遍历集合
//		Iterator<Entry<String, Integer>> it = set.iterator();
		//使用迭代器,返回的就是一个对应的对象。
		Iterator<Entry<String, Integer>> it = set.iterator();
		while(it.hasNext()){
			Entry<String, Integer> entry = it.next();
			//使用Entry对象中的方法getKey()和getValue()获取键与值
			String key = entry.getKey();
			Integer value = entry.getValue();
			System.out.println(key+"--"+value);
			
		}
		//增强for,获取map集合中的键值对对象。
		System.out.println("--------------------------");
		for (Entry<String, Integer> entry : set) {
			//使用Entry对象中的方法getKey()和getValue()获取键与值
			String key = entry.getKey();
			Integer value = entry.getValue();
			System.out.println(key+"--"+value);
		}
		//直接fore可以打出来。
//		for (Entry<String, Integer> entry : set) {
//			
//		}
	}
	
}

==================================

/*
 * 		自定义的Person类型
 * 
 */
public class Person {
	
	private String name ;
	private int age;
	public Person() {
		super();
	}
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
	//重写比较的方法。
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Person other = (Person) obj;
		if (age != other.age)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}
	
	
}

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

/*
 * HashMap存储自定义类型键值
 * 		Map集合保证key是唯一的
 * 		作为key的元素,必须重写hashCode方法和equals方法,以保证key唯一
 * 	快捷键生成:
 * 		自定义类型中一定要重写hashCode方法和equals方法,来保证key的唯一性
 * 
 */

public class HashMapSavePerson {

	public static void main(String[] args) {
//		show01();
		show02();
	}
	/*
	 * HashMap存续自定义类型键值
	 * 		key:String 类型
	 * 		value:Person类型
	 */
	private static void show01(){
		//创建HashMap集合
		HashMap<String,Person> map = new HashMap<>();
		//添加元素
		map.put("北京", new Person("张三",18));
		map.put("上海", new Person("李四",20));
		map.put("广州", new Person("王五",18));
		map.put("北京", new Person("赵六",18));
		//发现key已经重复了,下面的会替换掉上面的
		//遍历集合,首先把这个map集合转换为set集合进行遍历。
		Set<String> set = map.keySet();
		for (String key : set) {
			Person value = map.get(key);
			System.out.println(key+"-->"+value);
		}		
	}
	
	/*
	 * 	存储自定义类型
	 * 	key:Person类型
	 * 		Person类就必须重写hashCode方法和equals方法保证key唯一
	 * 	value:String类型
	 * 		可以重复
	 * 
	 */
	
	private static void show02(){
		//创建
		HashMap<Person,String> map = new HashMap<>();
		//添加元素
		map.put(new Person("张三",18), "英国");
		map.put(new Person("秦始皇",28), "秦国");
		map.put(new Person("普京",58), "俄罗斯");
		map.put(new Person("张三",18), "毛里求斯");
		//遍历
		Set<Entry<Person, String>> set = map.entrySet();
		for (Entry<Person, String> entry : set) {
			Person key = entry.getKey();
			String value = entry.getValue();
			System.out.println(key+"-->"+value);
		}
	}	
}

import java.util.List;
import java.util.Map;
import java.util.Set;

/*
 * JDK9的新特性
 * 		List接口,Set接口,Map接口里面增加了一个静态方法of,可以向集合一次性的添加多个元素
 * 		static <E> List <E> of (E.... elements)
 * 			当集合中存储的个数不在改变已经确定了,不再改变时使用
 * 			of只适用于List接口Set接口,Map接口 不使用接口的实现类
 *		一旦进行中这种方式的使用,表示不能进行其他的添加操作。
 * 			返回值是一个不能改变的量,集合不能在使用add,put方法添加元素,会抛出异常
 * 		注意事项:
 * 			Set接口和Map接口在调用of方法的时候不能有重复的元素,否则会抛出异常
 * 		
 * 
 */
public class DemoJdk9 {

	public static void main(String[] args) {
		//元素的个数已经确定的时候使用。
		List<String> list = List.of("a","b","a","c");
		//这样写类似数组,不能再添加了list.add不能添加,会抛异常
		
		Set<String> set = Set.of("a","b","a","d");//非法参数异常,不能存储重复元素,也不支持操作
		
		Map<String,Integer> map = Map.of("张三",18,"李四",19,"王五",20);	
		
	}
}

=================================

HashTable

java.util.HashTable<K,V>集合  implements Map<K,V>接口
HashTable:
最早期的单线程双列集合
	底层也是一个哈希表
不能存储空值空键
	和vector 在1.2版本之后被(HashMap)取代了,但是hashTable的子类Properties依然活跃
	Properties:是唯一和IO结合的集合
HashMap可以存储null值和null键,底层是哈希表,是一个线程不安全的集合,多线程

=============================

import java.util.HashMap;
import java.util.Hashtable;

public class HashTableCls {

	public static void main(String[] args) {
		HashMap<String, String> map = new HashMap<>();
		map.put(null, "a");
		map.put("b", null);
		map.put(null, null);
		System.out.println(map);
		
		System.out.println("-----------------------------------------");
		
		//hashTable不能存储空值空键
		Hashtable<String, String> table = new Hashtable<>();
		table.put(null, "a");//空指针异常
		table.put("b", null);//空指针异常
		table.put(null, null);//空指针异常
		
	}
}

Debug

/*
 * 	Debug调试程序:
 * 		可以让代码逐行执行,查看代码执行的过程,调试程序中出现的bug
 * 		双击行号,添加断点(每个方的第一行,哪里有bug添加到哪里)
 * 		选择debug执行程序,程序停留在添加的断点处,f8逐行执行车程序,
 * 		f7进入到方法中,shift+f8跳出方法
 * 		f9:跳到下一个断点,没有,就结束程序
 * 		ctrl+f2退出debug模式
 * 
 */

public class DemoDebug {

	public static void main(String[] args) {
		int a = 10;
		int b = 20;
		int sum = a + b;
		System.out.println(sum);
	}
	
}

=============================================

练习

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

/*
 * 	斗地主:有序
 * 		jdk9
 * 
 * 
 */
public class DouDiZhuTest {

	public static void main(String[] args) {
		//准备
		//创建一个map集合,存储牌的索引和组装io90好的牌
		HashMap<Integer,String> poker = new HashMap<>();
		//创建一个List集合,存储牌的索引
		ArrayList<Integer> pokerIndex = new ArrayList<>();
		//定义两个集合,存储花色和牌的序号
		List<String> colors = List.of("红桃","方片","梅花","黑桃");
		List<String> numbers = List.of("2","A","K","Q","J","10","9","8","7","6","5","4","3");
		//把大王和小王添加到集合中
		//定义牌的索引,第0号元素已经被认为是大王
		int index = 0;
		poker.put(index, "大王");
		pokerIndex.add(index);
		//这里是一号元素,一号元素被添加的HashMap中认定是小王。
		index++;
		poker.put(index, "小王");
		pokerIndex.add(index);
		index++;
		//循环嵌套遍历两个集合,组装52张牌,存到集合当中
		for(String number:numbers){
			for(String color:colors){
				//索引加字符串拼接成为行的牌
				poker.put(index, color+number);
				//下标索引自增,每添加一张牌索引增长添加的索引集合中。
				pokerIndex.add(index);
				index++;
			}
		}	
		System.out.println(poker);
		System.out.println(pokerIndex);
		//洗牌	shuffle
		Collections.shuffle(pokerIndex);
		System.out.println(pokerIndex);
		//发牌
		//定义四个集合,存储玩家牌的索引和底牌的索引
		ArrayList<Integer> play01 = new ArrayList<>();
		ArrayList<Integer> play02 = new ArrayList<>();
		ArrayList<Integer> play03 = new ArrayList<>();
		ArrayList<Integer> dipai = new ArrayList<>();
		//遍历村存储索引的List集合,获取每一个牌的索引,list集合的大小是Size
		for(int i = 0; i<pokerIndex.size();i++){
			Integer in = pokerIndex.get(i);
			//先判断底牌
			if(i>=51){
				//底牌
				dipai.add(in);
			}else if(i%3==0){
				play01.add(in);
			}else if(i%3==1){
				play02.add(in);
			}else if(i%3==2){
				play03.add(in);
			}
		}	
		//排序
		Collections.sort(play01);
		Collections.sort(play02);
		Collections.sort(play03);
		Collections.sort(dipai);
		//看牌调方法
		lookPoker("刘德华", poker,play01);
		lookPoker("周星驰", poker,play02);
		lookPoker("周润发", poker,play03);
		lookPoker("底牌", poker,dipai);
	} 
	//看牌
	//需要遍历这四个集合,定义一个方法,提高代码的复用性
	public static void lookPoker(String name,HashMap<Integer,String> poker, ArrayList<Integer> list){
		for (Integer key : list) {
			String value = poker.get(key);
			System.out.println(value+" ");
		}
		System.out.println();//打印完每一个玩家的牌换行
	}
}

------------------------------------------
import java.util.HashMap;
import java.util.Iterator;
import java.util.Scanner;

/*
 * 	练习:
 * 		计算一个字符串中每个字符创出现的次数
 * 	分析;使用Scanner获取用户输入的字符串
 * 	         创建Map集合key是字符串的字符,value是字符的个数
 * 	         遍历字符串,获取每一个字符
 * 		 这种获取,字符串需要转换为字符数组,遍历这个字符数组
 * 	    使用获取到的字符,去Map集合判断key是否存在
 * 		key存在:
 * 			通过字符(key) 获取value(字符个数)
 *			value++
 *			put(key, value) 把新的value 存储到map集合中
 *		key不存在
 *			map.put(key,1);
 *		遍历map集合,输出结果
 * 
 * 
 */
public class MapTest {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入一个字符串");
		String str = sc.next();
		//创建集合
		HashMap<Character,Integer> map = new HashMap<>();
		//遍历字符串,获取每一个字符, 这种获取,字符串需要转换为字符数组,遍历这个字符数组
		for(char c:str.toCharArray()){
			System.out.println("元素是"+c);
			//判断,不用输出征数组,直接进行map集合的判断即可。
			if(map.containsKey(c)){
				Integer value = map.get(c);
				value++;
				//存储
				map.put(c, value);
			}else{
				//key不存在
				map.put(c, 1);
			}
		}		
		//遍历输出
		for(Character key:map.keySet()){
			Integer value = map.get(key);
			System.out.println(key+"-->"+value);
		}
	}
	
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值