16-集合进阶下
双列集合的特点
- 双列集合一次需要存一对数据,分别为键和值
- 键不能重复,值可以重复
- 键和值是一一对应的,每一个键对应一个值
- 键+值这个整体我们称之为
键值对
或者键值对对象
,在java中叫做Entry对象
Map集合常用的api
方法名称 |
说明 |
V put(K key, V value) |
添加元素 |
V remove(Object key) |
根据键删除键值对元素 |
void clear() |
移除所有的键值对元素 |
boolean containsKey(Object key) |
判断集合是否包含指定的键 |
boolean containsValue(Object value) |
判断集合中是否包含指定的值 |
boolean isEmpty() |
判断集合是否为空 |
int size() |
集合的长度,也就是集合中键值对的个数 |
Set keySet() |
返回由键组成的set集合 |
Map集合的遍历方式
- 第一种 键找值
- 键组成的单列集合使用增强for
- 键组成的单列集合使用迭代器
- 键组成的单列集合使用lambda表达式
- 第二种 键值对
- entrySet(),返回一个包含所有键值对对象的set集合
- getKey()获取key,getValue()获取value
- 第三种 lambda表达式
package io.xiaoduo.mapPackage;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;
public class TraverseMap {
public static void main(String[] args) {
Map<String, String> mapArr = new HashMap<>();
mapArr.put("周杰伦", "不能说的秘密");
mapArr.put("陈奕迅", "富士山下");
Set<String> keys = mapArr.keySet();
for (String item : keys) {
String value = mapArr.get(item);
System.out.println(value);
}
Iterator<String> it = keys.iterator();
while (it.hasNext()) {
String key = it.next();
String value = mapArr.get(key);
System.out.println(value);
}
keys.forEach(item -> System.out.println(mapArr.get(item)));
System.out.println("----------");
Set<Map.Entry<String, String>> entries = mapArr.entrySet();
for (Map.Entry<String, String> item : entries) {
System.out.println(item.getKey());
System.out.println(item.getValue());
}
Iterator<Map.Entry<String, String>> it2 = entries.iterator();
while (it2.hasNext()) {
Map.Entry<String, String> item = it2.next();
System.out.println(item.getKey());
System.out.println(item.getValue());
}
entries.forEach(item -> System.out.println(item.getKey() + "=" + item.getValue()));
System.out.println("----------");
mapArr.forEach((String s, String s2) -> {
System.out.println(s + "=" + s2);
});
}
}
HashMap的基本使用
- 特点
- HashMap是Map里面的一个实现类
- 没有额外需要学习的方法,直接使用Map里面的方法就可以
- 由键决定的,无序,不重复,无索引
- HashMap跟HashSet底层原理是一模一样的,都是哈希表结构
- 总结
- HashMap底层是哈希表结构
- 依赖hashCode方法和equals方法保证键的唯一
- 如果键存的是自定义对象,需要重写hashCode和equals方法
- 如果值存的是自定义对象,则不需要重写
LinkedHashMap
- 由键决定:有序,不重复,无索引
- 这里的有序指的是保证储存顺序和去除的元素顺序一致
- 原理:底层数据结构依然是哈希表,只是每个键值对元素又额外的多了一个双链表的机制记录存储的顺序
LinkedHashMap<String, Integer> list = new LinkedHashMap<>();
list.put("a", 123);
list.put("b", 456);
list.put("c", 789);
System.out.println(list);
list.forEach((key, value) -> {
System.out.println(value);
});
TreeMap
- TreeMap跟TreeSet底层原理一样,都是红黑树结构
- 由键决定特性:不重复,无索引,可排序
- 可排序,对键进行排序
- 注意:默认按照键从小到大进行排序,也可以根据自己的排序规则
- 实现Comparable接口或者创建集合时传递Comparable比较器对象
package io.xiaoduo.mapPackage;
import java.util.TreeMap;
public class ExerciseTreeMap {
public static void main(String[] args) {
TreeMap<Student, String> tm = new TreeMap<>();
tm.put(new Student("周杰伦", 40), "台湾");
tm.put(new Student("鲍国安", 40), "山东");
tm.put(new Student("陈奕迅", 40), "香港");
tm.forEach((key, value) -> System.out.println(key + "->" + value));
String str = "aabbbcccddddeeeeeffffff";
TreeMap<Character, Integer> tm2 = new TreeMap<>();
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (tm2.containsKey(c)) {
int count = tm2.get(c);
tm2.put(c, ++count);
} else {
tm2.put(c, 1);
}
}
tm2.forEach((key, value) -> {
System.out.println(key + "->" + value);
});
}
}
总结
- TreeMap集合的特点是怎样的
- 不重复、无索引、可排序
- 底层基于红黑树实现排序,增删改查性能好
- TreeMap集合排序的两种方式
- 实现Comparable接口,指定比较规则
- 创建集合时传递Comparator比较器对象,指定比较规则
可选参数
- 用法和 js 的剩余参数一样
- 在方法中最多只能写一个可选参数
- 在方法的形参当中,如果除了可变参数还有其他的参数,那么可变参数要写在最后面
Collections常用的api
方法名称 |
说明 |
public static boolean addAlll(Collection c, T… elements) |
批量添加元素 |
public static void shuffle(List> list) |
打乱list集合的顺序 |
public static void sort(List list) |
排序 |
public static void sort(List list, Comparator c) |
根据指定的规则进行排序 |
public static int binarySearch (List list, T key) |
以二分查找法查找元素 |
public static void copy(List dest, List src) |
拷贝集合中的元素 |
public static int fill (List list, T obj) |
使用指定的元素填充集合 |
public static void max/min(Collection coll) |
根据默认的自然排序获取最大/小值 |
public static void swap(List> list, int i, int j) |
交换集合中指定位置的元素 |
练习
package io.xiaoduo.exercisePackage;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;
public class Test {
public static void main(String[] args) {
ArrayList<String> arr = new ArrayList<>();
Collections.addAll(arr, "范海萌", "黄金瑞", "杜倩", "冯舒明", "蒋奎", "雷康", "陈呈坤", "杨霄");
callName(arr);
callName(arr);
callName(arr);
}
public static void callName(ArrayList<String> arr) {
Random r = new Random();
int num = r.nextInt(arr.size());
System.out.println(num);
System.out.println(arr.get(num));
}
}
package io.xiaoduo.exercisePackage;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;
public class Test2 {
public static void main(String[] args) {
ArrayList<Student> arr = new ArrayList<>();
Collections.addAll(arr, new Student("范海萌", 1), new Student("黄金瑞", 0), new Student("杜倩", 0), new Student("冯舒明", 0), new Student("蒋奎", 1), new Student("雷康", 1), new Student("陈呈坤", 1), new Student("杨霄", 1), new Student("杨霄2", 1), new Student("杨霄3", 1));
double boy = 0;
double girl = 0;
for (int i = 0; i < 10; i++) {
if (boy / arr.size() * 100 < 70) {
callName(arr, 1);
boy++;
} else {
callName(arr, 0);
girl++;
}
}
System.out.println(boy);
System.out.println(girl);
}
public static void callName(ArrayList<Student> arr, int flag) {
Random r = new Random();
int num = r.nextInt(arr.size());
int gender = arr.get(num).getGender();
String name = arr.get(num).getName();
if (flag == 1) {
while (gender == 0) {
int num1 = r.nextInt(arr.size());
gender = arr.get(num1).getGender();
name = arr.get(num1).getName();
}
} else {
while (gender == 1) {
int num2 = r.nextInt(arr.size());
gender = arr.get(num2).getGender();
name = arr.get(num2).getName();
}
}
System.out.println(name);
}
}
package io.xiaoduo.exercisePackage;
import java.util.*;
public class Test3 {
public static void main(String[] args) {
ArrayList<Student> arr = new ArrayList<>();
Collections.addAll(arr, new Student("范海萌", 1), new Student("黄金瑞", 0), new Student("杜倩", 0), new Student("冯舒明", 0), new Student("蒋奎", 1), new Student("雷康", 1), new Student("陈呈坤", 1), new Student("杨霄", 1), new Student("杨霄2", 1), new Student("杨霄3", 1));
Map<String, Student> calledList = new HashMap<>();
for (int i = 0; i < 10; i++) {
callName(arr, calledList);
if (calledList.size() == arr.size()) {
System.out.println("开始新一轮点名");
}
}
calledList.forEach((key, value) -> {
System.out.println(key);
});
}
public static void callName(ArrayList<Student> arr, Map<String, Student> calledList) {
Random r = new Random();
int num = r.nextInt(arr.size());
String name = arr.get(num).getName();
Student student = arr.get(num);
if (!calledList.containsKey(name)) {
while (calledList.containsKey(name)) {
num = r.nextInt(arr.size());
name = arr.get(num).getName();
student = arr.get(num);
}
} else {
while (calledList.containsKey(name)) {
num = r.nextInt(arr.size());
name = arr.get(num).getName();
student = arr.get(num);
}
}
calledList.put(name, student);
}
}
package io.xiaoduo.exercisePackage;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class Test4 {
public static void main(String[] args) {
Map<String, ArrayList<String>> cityList = new HashMap<>();
ArrayList<String> l1 = new ArrayList<>();
Collections.addAll(l1, "南京市", "扬州市", "无锡市");
cityList.put("江苏省", l1);
ArrayList<String> l2 = new ArrayList<>();
Collections.addAll(l2, "武汉市", "孝感市", "宜昌市");
cityList.put("湖北省", l2);
ArrayList<String> l3 = new ArrayList<>();
Collections.addAll(l3, "石家庄市", "张家口市", "唐山市");
cityList.put("河北省", l3);
cityList.forEach((key, value) -> {
StringBuilder str = new StringBuilder();
value.forEach((item) -> {
str.append(item).append(",");
});
System.out.println(key + "=" + str);
});
}
}
斗地主洗牌
package io.xiaoduo.doudizhu1;
import java.util.ArrayList;
import java.util.Collections;
public class PokerGame {
static ArrayList<String> list = new ArrayList<>();
static {
String[] color = {"♥", "♦", "♠", "♣"};
String[] number = {"3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2"};
for (String c : color) {
for (String n : number) {
list.add(c + n);
}
}
list.add("小王");
list.add("大王");
}
public PokerGame() {
Collections.shuffle(list);
ArrayList<String> landlord = new ArrayList<>();
ArrayList<String> player1 = new ArrayList<>();
ArrayList<String> player2 = new ArrayList<>();
ArrayList<String> player3 = new ArrayList<>();
for (int i = 0; i < list.size(); i++) {
if (i <= 2) {
landlord.add(list.get(i));
continue;
}
if (i % 3 == 0) {
player1.add(list.get(i));
} else if (i % 3 == 1) {
player2.add(list.get(i));
} else if (i % 3 == 2) {
player3.add(list.get(i));
}
}
lookPoker("底牌", landlord);
lookPoker("玩家一", player1);
lookPoker("玩家二", player2);
lookPoker("我", player3);
}
public void lookPoker(String name, ArrayList<String> list) {
System.out.print(name + ":");
for (String s : list) {
System.out.print(s + " ");
}
System.out.println();
}
}
package io.xiaoduo.doudizhu2;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.TreeSet;
public class PokerGame {
static HashMap<Integer, String> pokerList = new HashMap<>();
static ArrayList<Integer> serialList = new ArrayList<>();
static {
String[] color = {"♥", "♦", "♠", "♣"};
String[] number = {"3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2"};
Integer serialNumber = 1;
for (String n : number) {
for (String c : color) {
pokerList.put(serialNumber, c + n);
serialList.add(serialNumber);
serialNumber++;
}
}
pokerList.put(serialNumber, "小王");
serialList.add(serialNumber);
serialNumber++;
serialList.add(serialNumber);
pokerList.put(serialNumber, "大王");
}
public PokerGame() {
Collections.shuffle(serialList);
TreeSet<Integer> landlord = new TreeSet<>();
TreeSet<Integer> player1 = new TreeSet<>();
TreeSet<Integer> player2 = new TreeSet<>();
TreeSet<Integer> player3 = new TreeSet<>();
for (int i = 0; i < serialList.size(); i++) {
if (i <= 2) {
landlord.add(serialList.get(i));
continue;
}
if (i % 3 == 0) {
player1.add(serialList.get(i));
} else if (i % 3 == 1) {
player2.add(serialList.get(i));
} else {
player3.add(serialList.get(i));
}
}
lookPoker("地主牌:", landlord);
lookPoker("玩家一:", player1);
lookPoker("玩家二:", player2);
lookPoker("大帅比:", player3);
}
public void lookPoker(String name, TreeSet<Integer> serialList) {
System.out.print(name);
for (Integer i : serialList) {
System.out.print(pokerList.get(i) + " ");
}
System.out.println();
}
}