今日内容
1.Map集合
-
Map接口概述
- 可以将键映射到值的对象
- 一个映射不能包含重复的键
- 每个键最多只能映射到一个值
-
Map接口和Collection接口的不同
- Map是双列的,Collection是单列的
- Map的键唯一,Collection的子体系Set是唯一的
- Map集合的数据结构针对键有效,跟值无关;
- Collection集合的数据结构是针对元素有效
-
Map集合的功能概述
- 添加功能
- V put(K key,V value):添加元素。这个其实还有另一个功能?替换
- 如果键是第一次存储,就直接存储元素,返回null
- 如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值
- 删除功能
- void clear(): 移除所有的键值对元素
- V remove(Object key):根据键删除键值对元素,并把值返回
- 判断功能
- boolean containsKey(Object key):判断集合是否包含指定的键
- boolean containsValue(Object value):判断集合是否包含指定的值
- boolean isEmpty():判断集合是否为空
- 获取功能
- Set<Map.Entry<K,V>> entrySet(): 返回一个键值对的Set集合
- V get(Object key):根据键获取值
- Set keySet():获取集合中所有键的集合
- Collection values():获取集合中所有值的集合
- 长度功能
- int size():返回集合中的键值对的对数
- 添加功能
-
案例演示
A:案例演示
Map集合的基本功能
V put(K key,V value)//键相同 值覆盖
V remove(Object key)
void clear()
boolean containsKey(Object key)
boolean containsValue(Object value)
boolean isEmpty()
int size()
-
Map集合的获取功能
- V get(Object key
- Set keySet()
- Collection values()
-
Map集合的遍历
-
获取所有键的集合
-
遍历键的集合,获取到每一个键
-
根据键找值
-
-
Map集合的遍历之键值对对象找键和值
-
获取所有键值对对象的集合
-
遍历键值对对象的集合,获取到每一个键值对对象
-
根据键值对对象找键和值
-
-
HashMap 集合键是Student值是String
- 键唯一 注意重写hashCode方法 和 equals 方法
2. LinkedHashMap
- LinkedHashMap
- Map 接口的哈希表和链接列表实现,具有可预知的迭代顺序
- LinkedHashMap的特点
- 底层的数据结构是链表和哈希表 元素有序 并且唯一
- 元素的有序性由链表数据结构保证 唯一性由 哈希表数据结构保证
- Map集合的数据结构只和键有关
3.TreeMap集合
-
TreeMap 键不允许插入null
-
TreeMap:
- 键的数据结构是红黑树,可保证键的排序和唯一性
- 排序分为自然排序和比较器排序
- 要实现Comparable 接口
- 线程是不安全的效率比较高
-
统计字符串中每个字符出现的次数
public class MyTest {
public static void main(String[] args) {
/*A:
案例演示:
需求:统计字符串中每个字符出现的次数
"aababcabcdabcde", 获取字符串中每一个字母出现的次数要求结果:a(5) b(4) c(3) d(2) e(1)*/
//"aababcabcdabcde"
// a(5) b(4) c(3) d(2) e(1)
/*
* a----5
* b----4
* c-----3
* d-----2
* e----1
* 我们观察发现这个数据是键值对应的数据
* 我们可以使用双列集合存起来,
* 遍历集合拼串
* 难点在于我怎么统计次数。
*
* 把字符串转换成字符数组,或者直接遍历字符串,把遍历的每一个字符作为键,把统计的个数作为值,存储到集合中
* */
LinkedHashMap<Character, Integer> hm = new LinkedHashMap<>();
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一段字符串");
String s = scanner.nextLine();
// char[] chars = s.toCharArray();
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
//如果不存在这个键,就把他存进去
if (!hm.containsKey(ch)) {
hm.put(ch, 1);
} else {
//取出上一次的值
Integer value = hm.get(ch);
//累加一下
value++;
//再存进去,键相同,值覆盖。
hm.put(ch, value);
}
}
//遍历集合拼串 a(5) b(4) c(3) d(2) e(1)
StringBuilder sb = new StringBuilder();
hm.forEach(new BiConsumer<Character, Integer>() {
@Override
public void accept(Character key, Integer value) {
sb.append(key).append("(").append(value).append(")");
}
});
String s1 = sb.toString();
System.out.println(s1);
}
}
4.集合嵌套
- HashMap 嵌套 HashMap
- 案例演示
import java.util.HashMap;
import com.heima.bean.Student;
public class Demo8_HashMap {
public static void main(String[] args) {
HashMap<Student, String> hs88=new HashMap<>();
hs88.put(new Student("张三",23),"北京");
hs88.put(new Student("李四",24),"北京");
hs88.put(new Student("李四",25),"广州");
hs88.put(new Student("王五",26),"深圳");
HashMap<Student, String> hs99=new HashMap<>();
hs99.put(new Student("唐生",1023),"北京");
hs99.put(new Student("孙悟空",1024),"北京");
hs99.put(new Student("猪八戒",1025),"广州");
hs99.put(new Student("沙和尚",1026),"深圳");
HashMap<HashMap<Student, String>, String> hm=new HashMap<>();
hm.put(hs88, "第88期基础班");
hm.put(hs99, "第99期基础班");
for (HashMap<Student, String> map1 : hm.keySet()) {//hm.keySet()代表双列集合中键的集合
String s=hm.get(map1);//get(map1)根据键集合获取值对象
System.out.println(s);
for (Student skey : map1.keySet()) {
System.out.println(skey+"="+map1.get(skey));
}
}
}
}
- HashMap嵌套ArrayList
/*
*需求:
*假设HashMap集合的元素是ArrayList。有3个。
*每一个ArrayList集合的值是字符串。
*元素我已经完成,请遍历。
*结果:
* 三国演义
* 吕布
* 周瑜
* 笑傲江湖
* 令狐冲
* 林平之
* 神雕侠侣
* 郭靖
* 杨过
*/
public class HashMapIncludeArrayListDemo {
public static void main(String[] args) {
// 创建集合对象
HashMap<String, ArrayList<String>> hm = new HashMap<String, ArrayList<String>>();
// 创建元素集合1
ArrayList<String> array1 = new ArrayList<String>();
array1.add("吕布");
array1.add("周瑜");
hm.put("三国演义", array1);
// 创建元素集合2
ArrayList<String> array2 = new ArrayList<String>();
array2.add("令狐冲");
array2.add("林平之");
hm.put("笑傲江湖", array2);
// 创建元素集合3
ArrayList<String> array3 = new ArrayList<String>();
array3.add("郭靖");
array3.add("杨过");
hm.put("神雕侠侣", array3);
// 遍历集合
Set<String> set = hm.keySet();
for (String key : set) {
System.out.println(key);
ArrayList<String> value = hm.get(key);
for (String s : value) {
System.out.println("\t" + s);
}
}
}
}
- ArrayList嵌套HashMap
public class MyTest2 {
public static void main(String[] args) {
/*
* 案例演示
集合嵌套之ArrayList嵌套HashMap
假设ArrayList集合的元素是HashMap。有3个。
每一个HashMap集合的键和值都是字符串。
周瑜---小乔
吕布---貂蝉
郭靖---黄蓉
杨过---小龙女
令狐冲---任盈盈
林平之---岳灵珊
*/
HashMap<String, String> sgMap = new HashMap<>();
sgMap.put("周瑜", "小乔");
sgMap.put("吕布", "貂蝉");
HashMap<String, String> sdMap = new HashMap<>();
sdMap.put("郭靖", "黄蓉");
sdMap.put("杨过", "小龙女");
HashMap<String, String> xaMap = new HashMap<>();
xaMap.put("令狐冲", "任盈盈");
xaMap.put("林平之", "岳灵珊");
ArrayList<HashMap<String, String>> maxList = new ArrayList<>();
maxList.add(sgMap);
maxList.add(xaMap);
maxList.add(sdMap);
for (HashMap<String, String> minMap : maxList) {
minMap.forEach(new BiConsumer<String, String>() {
@Override
public void accept(String key, String value) {
System.out.println(key + "--------" + value);
}
});
System.out.println();
}
}
}
5.HashMap和Hashtable的区别
- HashMap和Hashtable的区别
- HashMap: 线程不安全,效率高.允许null值和null键
- Hashtable: 线程安全 , 效率低.不允许null值和null键
6.Collections工具类
-
Collections类概述: 针对集合操作 的工具类
-
Collections成员方法
public static void sort(List list): 排序,默认按照自然顺序
public static int binarySearch(List<?> list,T key): 二分查找
public static T max(Collection<?> coll): 获取最大值
public static void reverse(List<?> list): 反转
public static void shuffle(List<?> list): 随机置换 -
案例演示
public class MyTest {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
list.add(20);
list.add(204);
list.add(208);
list.add(20);
list.add(280);
// list.sort();
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer a, Integer b) {
return a - b;
}
});
System.out.println(list);
int i = Collections.binarySearch(list, 208);
System.out.println(i);
Integer max = Collections.max(list);
Integer min = Collections.min(list);
System.out.println(max);
System.out.println(min);
Collections.reverse(list);
System.out.println(list);
//随机打乱集合中元素的顺序
Collections.shuffle(list);
System.out.println(list);
}
}
7.模拟斗地主洗牌和发牌(无序)
public class Test {
public static void main(String[] args) {
//先得有一副牌
ArrayList<String> pokerBox = new ArrayList<>();
//生成54张牌,放进牌盒
String[] colors = {"♣", "♠", "♦", "♥"};
String[] nums = {"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"};
for (String num : nums) {
for (String color : colors) {
pokerBox.add(num.concat(color));
}
}
//手动添加大小王
pokerBox.add("大王");
pokerBox.add("小王");
//洗牌
Collections.shuffle(pokerBox);
Collections.shuffle(pokerBox);
Collections.shuffle(pokerBox);
//发牌: 三个人 就是三个集合,还有一副底牌,也是个集合
ArrayList<String> 高进 = new ArrayList<>();
ArrayList<String> 刀仔 = new ArrayList<>();
ArrayList<String> 星仔 = new ArrayList<>();
ArrayList<String> 底牌 = new ArrayList<>();
/* int i = 0;
while (i < 51) {
高进.add(pokerBox.get(i));
i++;
刀仔.add(pokerBox.get(i));
i++;
星仔.add(pokerBox.get(i));
i++;
}
底牌.add(pokerBox.get(i));
i++;
底牌.add(pokerBox.get(i));
i++;
底牌.add(pokerBox.get(i));
i++;
System.out.println(高进);
System.out.println(刀仔);
System.out.println(星仔);
System.out.println(底牌);
*/
for (int i = 0; i < pokerBox.size(); i++) {
if (i >= pokerBox.size() - 3) {
底牌.add(pokerBox.get(i));
} else if (i % 3 == 0) {
高进.add(pokerBox.get(i));
} else if (i % 3 == 1) {
刀仔.add(pokerBox.get(i));
} else {
星仔.add(pokerBox.get(i));
}
}
//看牌
lookPoker("高进", 高进);
lookPoker("刀仔", 刀仔);
lookPoker("星仔", 星仔);
lookPoker("底牌", 底牌);
}
private static void lookPoker(String name, ArrayList<String> list) {
System.out.println(name);
for (String s : list) {
System.out.print(s + "\t");
}
System.out.println();
}
}
8.模拟斗地主洗牌和发牌(有序)
public class Test {
public static void main(String[] args) {
//创建集合,生成牌合
TreeMap<Integer, String> Porkerbox = new TreeMap<>();
//定义54牌(除过大小王)
String[] colors = {"♣", "♠", "♦", "♥"};
String[] numbers = {"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"};
//创建一个Arraylist集合来存储对牌的索引
ArrayList<Integer> index = new ArrayList<>();
//定义初始索引为1
int i=0;
//对花色和数字进行遍历
for (String color : colors) {
for (String number : numbers) {
Porkerbox.put(i,color+number);
//将定义的索引加入集合中
index.add(i);
//每添加一张牌索引+1
i++;
}
//存放大小王
Porkerbox.put(i,"大王");
index.add(i);
i++;
Porkerbox.put(i,"小王");
index.add(i);
i++;
}
//洗牌
Collections.shuffle(index);
//根据索引去发牌
TreeSet<Integer> 高进 = new TreeSet<>();
TreeSet<Integer> 刀仔 = new TreeSet<>();
TreeSet<Integer> 星仔 = new TreeSet<>();
TreeSet<Integer> 底牌 = new TreeSet<>();
for (int j = 0; j < Porkerbox.size(); j++) {
if (j >= Porkerbox.size() - 3) {
底牌.add(index.get(j));
} else if (j % 3 == 0) {
高进.add(index.get(j));
} else if (j % 3 == 1) {
刀仔.add(index.get(j));
} else {
星仔.add(index.get(j));
}
}
//看牌
lookPoker("高进", 高进,Porkerbox);
lookPoker("刀仔", 刀仔,Porkerbox);
lookPoker("星仔", 星仔,Porkerbox);
lookPoker("底牌", 底牌,Porkerbox);
}
private static void lookPoker(String name, TreeSet<Integer> index, TreeMap<Integer, String> porkerbox) {
System.out.println(name+"的底牌是:");
for (Integer i : index) {
System.out.print(porkerbox.get(i+""));
}
System.out.println();
}
}