Java之Map集合接口功能(介绍HashMap LinkedHashMap TreeMap Hashtable)以及Collections的使用 泛型之固定上下边界

set的底层其实是由Map实现的
只是值为Object 不显示而已
在这里插入图片描述
注意 各种底层算法(哈希算法,二叉树算法,链表算法 )都只是针对map中的key!!
Map<k,v>以键值对的形式存在
Map接口一些常用的功能
1.添加功能Value put(K,V)
如果K相同则返回覆盖值V 如果没有为null
2.删除功能clear()
还有Value remove(Key) 根据键删除值! 返回键对应的值
3.判断功能
boolean containKey(key)
boolean containValue(Value)
boolean isEmpty()
4.获取功能
Collections< Values > .values()//获取map中所有的值 并构成集合
set< key >. KeySet()//获取map中所有的键 并构成集合
Map.entry<key,Value> . EntrySet( ) . //把Map中的键值对包装在一起 组成一个新集合!
也就是说看成一个新的对象 Map,Entry<key,Value>
5.长度功能
int size()

Map集合不能直接迭代
第一种方法
1.先获取所有的键值集合set
2.迭代器遍历集合
or
fore循环

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

public class Demo2_Iterator {

	/**
	 * 通过查看Map集合的api发现没有iterator方法,那么双列集合如何迭代呢?
	 * 根据键获取值
	 */
	public static void main(String[] args) {
		Map<String, Integer> map = new HashMap<>();
		map.put("张三", 23);
		map.put("李四", 24);
		map.put("王五", 25);
		map.put("赵六", 26);
		
//		Integer i = map.get("张三");					//根据键获取值
//		System.out.println(i);
		
		//获取所有的键
		/*Set<String> keySet = map.keySet();			//获取所有键的集合
		Iterator<String> it = keySet.iterator();	//获取迭代器
		while(it.hasNext()) {						//判断集合中是否有元素
			String key = it.next();					//获取每一个键
			Integer value = map.get(key);			//根据键获取值
			System.out.println(key + "=" + value);
		}*/
		
		//使用增强for循环遍历
		for(String key : map.keySet()) {			//map.keySet()是所有键的集合
			System.out.println(key + "=" + map.get(key));
		}
	}

}

第二种 迭代方法
把双列集合变成单列集合
.entrySet()
Map.Entry<key,Value> 其子类为 Entry<key,Value>
接口.接口这样的用法 说明Entry是Map的子接口

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

public class Demo3_Iterator {

	/**
	 * Map集合的第二种迭代,根据键值对对象,获取键和值
	 *  A:键值对对象找键和值思路:
		* 获取所有键值对对象的集合
		* 遍历键值对对象的集合,获取到每一个键值对对象
		* 根据键值对对象找键和值
	 */
	public static void main(String[] args) {
		Map<String, Integer> map = new HashMap<>();
		map.put("张三", 23);
		map.put("李四", 24);
		map.put("王五", 25);
		map.put("赵六", 26);
		
		//Map.Entry说明Entry是Map的内部接口,将键和值封装成了Entry对象,并存储在Set集合中
		/*Set<Map.Entry<String, Integer>> entrySet = map.entrySet();
		//获取每一个对象
		Iterator<Map.Entry<String, Integer>> it = entrySet.iterator();
		while(it.hasNext()) {
			//获取每一个Entry对象
			Map.Entry<String, Integer> en = it.next();	//父类引用指向子类对象
			//Entry<String, Integer> en = it.next();	//直接获取的是子类对象
			String key = en.getKey();					//根据键值对对象获取键
			Integer value = en.getValue();				//根据键值对对象获取值
			System.out.println(key + "=" + value);
		}*/
		
		for(Entry<String, Integer> en : map.entrySet()) {
			System.out.println(en.getKey() + "=" + en.getValue());
		}
	}

}

HashMap
自定义类要重写 equals 和hashcode方法

LinkedHashMap
怎么存就这么取

TreeMap
可以对键进行排序
自定义类的话(方法有两种)
法一:实现comparable接口并重写类中的compareTo
法二:加入比较器Comparator

小练习
判断每次字符出现的次数

import java.util.HashMap;

public class Main{
	public static void main(String[] args) {
		String s = "abbcccddddeeeeeeeeee";
		char[] arr = s.toCharArray();
		HashMap<Character,Integer> map =new HashMap<Character, Integer>();
		for (char c : arr) {
			map.put(c,map.containsKey(c) ? map.get(c)+1 : 1);
		}
		System.out.println(map);
	}
}

在这里插入图片描述

HashMap嵌套

import java.util.HashMap;

import com.heima.bean.Student;

public class Demo8_HashMapHashMap {

	/**
	 * * A:案例演示
	 * 集合嵌套之HashMap嵌套HashMap
	 * 
	 * 需求:
	 * 双元课堂有很多基础班
	 * 第88期基础班定义成一个双列集合,键是学生对象,值是学生的归属地
	 * 第99期基础班定义成一个双列集合,键是学生对象,值是学生的归属地
	 * 
	 * 无论88期还是99期都是班级对象,所以为了便于统一管理,把这些班级对象添加到双元课堂集合中
	 */
	public static void main(String[] args) {
		//定义88期基础班
		HashMap<Student, String> hm88 = new HashMap<>();
		hm88.put(new Student("张三", 23), "北京");
		hm88.put(new Student("李四", 24), "北京");
		hm88.put(new Student("王五", 25), "上海");
		hm88.put(new Student("赵六", 26), "广州");
		
		//定义99期基础班
		HashMap<Student, String> hm99 = new HashMap<>();
		hm99.put(new Student("唐僧", 1023), "北京");
		hm99.put(new Student("孙悟空",1024), "北京");
		hm99.put(new Student("猪八戒",1025), "上海");
		hm99.put(new Student("沙和尚",1026), "广州");
		
		//定义双元课堂
		HashMap<HashMap<Student, String>, String> hm = new HashMap<>();
		hm.put(hm88, "第88期基础班");
		hm.put(hm99, "第99期基础班");
		
		//遍历双列集合
		for(HashMap<Student, String> h : hm.keySet()) {		//hm.keySet()代表的是双列集合中键的集合
			String value = hm.get(h);						//get(h)根据键对象获取值对象
			//遍历键的双列集合对象
			for(Student key : h.keySet()) {					//h.keySet()获取集合总所有的学生键对象
				String value2 = h.get(key);
				
				System.out.println(key + "=" + value2 + "=" + value);
			}
		}
		
	}

}

Hashtable
线程安全 效率低 命运和Vector一样被替代了

Collections 工具类的使用
只针对于list
Collecitons中的常见方法
public static < T > void sort(List< T > list)
public static < T > int binarySearch(List<?> list,T key)
public static < T > T max(Collection<?> coll)
public static void reverse(List<?> list)
public static void shuffle(List<?> list)

import java.util.ArrayList;
import java.util.Collections;

public class Demo1_Collecitons {

	/**
	 * 	Collecitons中的常见方法
	 * 	public static <T> void sort(List<T> list)
		public static <T> int binarySearch(List<?> list,T key)
		public static <T> T max(Collection<?> coll)
		public static void reverse(List<?> list)
		public static void shuffle(List<?> list)
	 */
	public static void main(String[] args) {
		//demo1();
		//demo2();
		ArrayList<String> list = new ArrayList<>();
		list.add("a");
		list.add("c");
		list.add("d");
		list.add("g");
		list.add("f");
		//System.out.println(Collections.max(list)); 			//根据默认排序结果获取集合中的最大值
		//Collections.reverse(list);							//反转集合
		Collections.shuffle(list);								//随机置换,可以用来洗牌
		System.out.println(list);
	}

	public static void demo2() {
		ArrayList<String> list = new ArrayList<>();
		list.add("a");
		list.add("c");
		list.add("d");
		list.add("f");
		list.add("g");
		
		System.out.println(Collections.binarySearch(list, "c"));
		System.out.println(Collections.binarySearch(list, "b"));  //返回-2 为 :-插入值-1
	}

	public static void demo1() {
		ArrayList<String> list = new ArrayList<>();
		list.add("c");
		list.add("a");
		list.add("a");
		list.add("b");
		list.add("d");
		
		System.out.println(list);
		Collections.sort(list);						//将集合排序
		System.out.println(list);
	}

}

最后小练习
模拟斗地主
1.存牌
ArrayList< Integer > list 存索引
HashMap<Integer,String> hm存 索引值和牌的内容
2.洗牌 洗索引
Collections.shuffle(list);
3.发牌 发索引
TreeSet< Integer > player1 = new TreeSet<>(); //拥有自动排序的功能
4.看牌 通过索引找到牌的内容并打印

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

public class Main{
	public static void main(String[] args) {
		//1,买一副扑克,其实就是自己创建一个集合对象,将扑克牌存储进去
		String[] num = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
		String[] color = {"方片","梅花","红桃","黑桃"};
		ArrayList<Integer> list = new ArrayList<>();
		HashMap<Integer,String> hm = new HashMap<>();
		int index = 0;
		
		//拼接扑克牌并索引和扑克牌存储在hm中
		for(String s1 : num) {											//获取数字
			for(String s2 : color) {									//获取颜色
				hm.put(index, s2.concat(s1));
				list.add(index);										//将索引0到51添加到list集合中
				index++;
			}
		}
		hm.put(index, "小王");
		list.add(index);	
		index++;
		hm.put(index, "大王");
		list.add(index);	
//		2.洗牌
		Collections.shuffle(list);
		
//		3.发牌   添加的仅仅只是索引
		TreeSet<Integer> player1 = new TreeSet<>();
		TreeSet<Integer> player2 = new TreeSet<>();
		TreeSet<Integer> me = new TreeSet<>();
		TreeSet<Integer> dipai = new TreeSet<>();
		
		for(int i = 0; i < list.size(); i++) {
			if(i >= list.size() - 3) {
				dipai.add(list.get(i));							//将三张底牌存储在底牌集合中
			}else if(i % 3 == 0) {
				player1.add(list.get(i));
			}else if(i % 3 == 1) {
				player2.add(list.get(i));
			}else {
				me.add(list.get(i));
			}
		}
//		4.看牌
		lookPoker(hm,player1,"熊海涛");
		lookPoker(hm,player2,"武晓慧");
		lookPoker(hm,me,"杨瑞卿");
		lookPoker(hm,dipai,"底牌");
		
		
	}
	public static void lookPoker(HashMap<Integer,String> hm,TreeSet<Integer> player,String name)
	{
		System.out.print(name+"的牌是:");
		for(Integer i : player) {
			System.out.print(hm.get(i)+" ");
		}
		System.out.println();
	}
}

所以最后的牌是按照顺序打印的
在这里插入图片描述

泛型固定上边界
? extends E
用于addAll(Collection c)
表示向父类集合可以添加子类集合

泛型固定下边界
? super E
用于TreeSet 或TreeMap 中的比较器方法中
表示父类的比较器 子类也能用

演示代码

import java.util.ArrayList;
import java.util.Comparator;
import java.util.TreeSet;

import com.heima.bean.BaseStudent;
import com.heima.bean.Student;

public class Demo2_Genric {

	/**
	 * 泛型固定下边界
	 * ? super E  
	 * 
	 * 泛型固定上边界
	 * ? extends E
	 */
	public static void main(String[] args) {
		//demo1();
		TreeSet<Student> ts1 = new TreeSet<>(new CompareByAge());
		ts1.add(new Student("张三", 33));
		ts1.add(new Student("李四", 13));
		ts1.add(new Student("王五", 23));
		ts1.add(new Student("赵六", 43));
		
		TreeSet<BaseStudent> ts2 = new TreeSet<>(new CompareByAge());
		ts2.add(new BaseStudent("张三", 33));
		ts2.add(new BaseStudent("李四", 13));
		ts2.add(new BaseStudent("王五", 23));
		ts2.add(new BaseStudent("赵六", 43));
		
		System.out.println(ts2);
	}

	public static void demo1() {
		ArrayList<Student> list1 = new ArrayList<>();
		list1.add(new Student("张三", 23));
		list1.add(new Student("李四", 24));
		
		ArrayList<BaseStudent> list2 = new ArrayList<>();
		list2.add(new BaseStudent("王五", 25));
		list2.add(new BaseStudent("赵六", 26));
		
		list1.addAll(list2);
	}

}

class CompareByAge implements Comparator<Student> {

	@Override
	public int compare(Student s1, Student s2) {
		int num = s1.getAge() - s2.getAge();
		return num == 0 ? s1.getName().compareTo(s2.getName()) :  num;
	}
	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

黑瞳丶

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

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

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

打赏作者

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

抵扣说明:

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

余额充值