2020.5.20 课堂笔记
Map接口
-
双列集合的接口,存放一个键映射到值的对象,键不能重复,每个键可以最多映射到一个值。
-
Map接口和Collection接口的不同
- Map接口:是双列的,键映射值,键唯一。数据结构针对键有效。
- Collection接口:单列的,只有Set接口的子集合元素唯一,数据结构针对元素有效。
-
Map接口和其子集合
- HashMap:键的唯一是靠重写hash方法和equals方法来保证。
- LinkedHashMap:底层数据结构是链表和哈希表,链表保证有序,哈希表保证键唯一。
- TreeMap:底层数据结构是二叉树,保证了键值的排序和唯一
- HashMap和Hashtable的区别
- HashMap:允许null值和null键,线程不安全,效率高。
- Hashtable:不允许null值和null键,线程安全,效率底。
- 其他都是相同的
代码
package org.westos.demo0519.HashMap;
/*Author:LH
CreatTime:2020.05.20.15:32*/
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
public class Test {
public static void main(String[] args) {
HashMap<Integer, String> map = new HashMap<>();
map.put(13, "张三");
map.put(14,"李四");
map.put(15,"张三");
map.put(16,"李四");
map.put(18,"张三");
map.put(19,"李四");
// 添加元素,返回此键映射的旧元素,如果有就返回,没有就返回null.
String s = map.put(13, "张三2");
System.out.println(s); //此处返回第一个键映射的“张三”。
map.put(14,"李四2");// 键相同,值覆盖。覆盖掉第一个键映射的值李四。
System.out.println(map);
String s1 = map.remove(14);
System.out.println(s1);
System.out.println(map);
// 删除的键不存在,就返回null.
String s2 = map.remove(19);
// 将HashMap转换成 Set集合。
Set<Map.Entry<Integer, String>> entries = map.entrySet();
for (Map.Entry<Integer, String> entry : entries) {
System.out.println(entry);
}
// 将map集合的键存到set集合中。
Set<Integer> integers = map.keySet();
for (Integer integer : integers) {
// 遍历键,拿出映射的值
System.out.println(map.get(integer));
}
System.out.println("+++++++++++++");
// 判断是否存在指定的键或者值
System.out.println(map.containsKey(17));
System.out.println(map.containsKey(18));;
System.out.println(map.containsValue("张三"));
Collection<String> values = map.values();
System.out.println("===========");
// 获取值的集合,并遍历
values.forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
}
}
2.package org.westos.demo0519.HashMap;
/*Author:LH
CreatTime:2020.05.21.9:12*/
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
//如果Student不重写hash方法和equals方法,就会将所有的数据存进去,因为每次每次new出来的
//对象地址都不相同,所以hash值也不相同。
//重写hash方法和equals方法,就会把名字和年龄相同的去掉。
public class TestStudent {
public static void main(String[] args) {
HashMap<Student, String> hashMap = new HashMap<>();
hashMap.put(new Student("刘兴",18),"s001");
hashMap.put(new Student("刘兴",19),"s002");
hashMap.put(new Student("张三",18),"s001");
hashMap.put(new Student("赵四",20),"s003");
hashMap.put(new Student("刘兴",19),"s002");
System.out.println(hashMap);
System.out.println("==========");
// 遍历方式一,获取出键值对对象,遍历并获取键和值
Set<Map.Entry<Student, String>> entries = hashMap.entrySet();
for (Map.Entry<Student, String> node : entries) {
Student key = node.getKey();
String value = node.getValue();
System.out.println(key.toString()+"=="+value);
}
System.out.println("=========");
// 遍历方式二,获取键的集合,通过遍历键获取值
Set<Student> keySet = hashMap.keySet();
keySet.forEach(new Consumer<Student>() {
@Override
public void accept(Student student) {
String s = hashMap.get(student);
System.out.println(student.toString()+"=="+s);
}
});
System.out.println("==============");
// 遍历方式三,通过JDK1.8提供的方法foreach获取键和值
hashMap.forEach(new BiConsumer<Student, String>() {
@Override
public void accept(Student student, String s) {
System.out.println(student.toString()+"=="+s);
}
});
}
}
package org.westos.demo0519.HashMap;
/*Author:LH
CreatTime:2020.05.18.15:16*/
import java.util.Objects;
public class Student {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public Student() {
}
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 "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age &&
Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
3.package org.westos.demo0519.HashMap;
/*Author:LH
CreatTime:2020.05.20.16:42*/
//存取顺序一致,自定义对象也要重写hash方法和equals方法
import java.util.LinkedHashMap;
public class LinkeHashMap {
public static void main(String[] args) {
LinkedHashMap<Integer, Integer> map = new LinkedHashMap<>(17, 0.8f, false);
map.put(12,12);
map.put(14,15);
map.put(15,13);
map.put(12,17);
map.put(8,15);
map.put(1,13);
Integer remove = map.remove(15);
System.out.println(map);
}
}
4.package org.westos.demo0519.TreeMap;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/*Author:LH
CreatTime:2020.05.21.10:40*/
//hashmap集合嵌套,并按照此方式打印出来。
/*基础班
张三 20
李四 22
就业班
王五 21
赵六 23*/
public class Test2 {
public static void main(String[] args) {
// 先将基本数据存在小的双列集合中
HashMap<String, Integer> minhashMap1 = new HashMap<>();
minhashMap1.put("张三",20);
minhashMap1.put("李四",22);
HashMap<String, Integer> minhashMap2 = new HashMap<>();
minhashMap2.put("王五",21);
minhashMap2.put("赵六",23);
// 再将班级信息存到大的集合中
HashMap<String, HashMap<String, Integer>> hashMap = new HashMap<>();
hashMap.put("基础班",minhashMap1);
hashMap.put("就业班",minhashMap2);
// 遍历
// 先获取班级信息
Set<Map.Entry<String, HashMap<String, Integer>>> entries = hashMap.entrySet();
for (Map.Entry<String, HashMap<String, Integer>> entry : entries) {
String key = entry.getKey();
HashMap<String, Integer> value = entry.getValue();
System.out.println(key);
// 通过获取的班级信息,在获取班级中成员的信息
Set<Map.Entry<String, Integer>> entries1 = value.entrySet();
for (Map.Entry<String, Integer> entry1 : entries1) {
String key1 = entry1.getKey();
Integer value1 = entry1.getValue();
System.out.println('\t'+key1+"=="+value1);
}
System.out.println();
}
}
}
5.package org.westos.demo0519.TreeMap;
/*Author:LH
CreatTime:2020.05.21.10:16*/
import java.util.TreeMap;
import java.util.function.BiConsumer;
//使用自然排序键存储自定义对象,对象要实现 Comparable<Student>接口,重写 compareTo方法
//才能保证唯一和排序。
public class TestStudent {
public static void main(String[] args) {
TreeMap<Student, String> treeMap = new TreeMap<>();
treeMap.put(new Student("张三",18),"s001");
treeMap.put(new Student("张三",19),"s002");
treeMap.put(new Student("赵四",18),"s003");
treeMap.put(new Student("王五",20),"s004");
treeMap.put(new Student("张三",19),"s005");
treeMap.forEach(new BiConsumer<Student, String>() {
@Override
public void accept(Student student, String s) {
System.out.println(student.toString()+"==="+s);
}
});
}
}
package org.westos.demo0519.TreeMap;
/*Author:LH
CreatTime:2020.05.18.15:16*/
import java.util.Objects;
public class Student implements Comparable<Student> {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public Student() {
}
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 "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(Student o) {
int num =this.age-o.age;
int num2=num==0?this.name.compareTo(o.name):num;
return num2;
}
}
6. package org.westos.demo0519.TreeMap;
/*Author:LH
CreatTime:2020.05.21.10:28*/
import java.util.Comparator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
//使用比较器排序
public class TestStudent2 {
public static void main(String[] args) {
TreeMap<Student2, String> treeMap = new TreeMap<>(new Comparator<Student2>() {
@Override
public int compare(Student2 o1, Student2 o2) {
// 此处的逻辑根据需要重写
int i = o1.getAge() - o2.getAge();
int i2=i==0?o1.getName().compareTo(o2.getName()):i;
return i2;
}
});
treeMap.put(new Student2("张三",18),"s001");
treeMap.put(new Student2("张三",19),"s002");
treeMap.put(new Student2("赵四",18),"s003");
treeMap.put(new Student2("王五",20),"s004");
treeMap.put(new Student2("张三",19),"s005");
Set<Map.Entry<Student2, String>> entries = treeMap.entrySet();
for (Map.Entry<Student2, String> entry : entries) {
Student2 key = entry.getKey();
String value = entry.getValue();
System.out.println(key.toString()+"=="+value);
}
}
}
Collections工具类
- 它是集合的工具类,所有的方法都是静态方法,可以直接类名调方法
- 常见方法:
- 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):随机打乱集合。
斗地主发牌
package org.westos.demo0519.playgame;
/*Author:LH
CreatTime:2020.05.19.22:49*/
//斗地主发牌游戏
import java.util.ArrayList;
import java.util.Collections;
import java.util.TreeMap;
import java.util.function.BiConsumer;
public class Game {
public static void main(String[] args) {
// 先将牌组拼好放在集合中
ArrayList<String> list = new ArrayList<>();
String []shape={"♠","♥","♦","♣"};
String [] num={"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
for (String s1 : num) {
for (String s2 : shape) {
String s = s1.concat(s2);
list.add(s);
}
}
list.add("☀");
list.add("☼");
// 将单列集合转换成双列集合,存放map集合
TreeMap<Integer, String> map = new TreeMap<>();
for (int i = 0; i < list.size(); i++) {
map.put(i,list.get(i));
}
// 取出双列集合的键存放在新list集合,便于发牌和洗牌,只针对键进行,再通过键找到value。
ArrayList<Integer> list1 = new ArrayList<>();
map.forEach(new BiConsumer<Integer, String>() {
@Override
public void accept(Integer key, String value) {
list1.add(key);
}
});
Collections.shuffle(list1);
ArrayList<Integer> person1 = new ArrayList<>();
ArrayList<Integer> person2 = new ArrayList<>();
ArrayList<Integer> person3 = new ArrayList<>();
ArrayList<Integer> publicCard = new ArrayList<>();
for (int i = 0; i < list1.size(); ) {
if (i<list1.size()-3){
person1.add(list1.get(i));
person2.add(list1.get(i+1));
person3.add(list1.get(i+2));
i+=3;
}else {
publicCard.add(list1.get(i));
i++;
}
}
Collections.sort(person1);
Collections.sort(person2);
Collections.sort(person3);
for (Integer integer : person1) {
System.out.print(map.get(integer)+'\t');
}
System.out.println();
for (Integer integer : person2) {
System.out.print(map.get(integer)+'\t');
}
System.out.println();
for (Integer integer : person3) {
System.out.print(map.get(integer)+'\t');
}
System.out.println();
for (Integer integer : publicCard) {
System.out.print(map.get(integer)+'\t');
}
}
}
查找重复元素
package org.westos.demo0519.playgame;
/*Author:LH
CreatTime:2020.05.21.10:56*/
import java.util.HashMap;
/*需求:统计字符串中每个字符出现的次数
"aababcabcdabcde",获取字符串中每一个字母出现的次数要求结果:a(5)b(4)c(3)d(2)e(1)*/
public class Test {
public static void main(String[] args) {
String s="aababcabcdabcde";
// 创建双列集合,把已知的元素当作键和值
HashMap<Character,Character> hashMap = new HashMap<>();
hashMap.put('a','a');
hashMap.put('b','b');
hashMap.put('c','c');
hashMap.put('d','d');
hashMap.put('e','e');
int a=0;
int b=0;
int c=0;
int d=0;
int e=0;
for (int i = 0; i < s.length(); i++) {
// 向已知的集合中存字符串,有相同键,值就会值覆盖,返回旧值,然后做累加就知道数量
Character put = hashMap.put(s.charAt(i), s.charAt(i));
if (put.equals('a')){
a++;
}else if (put.equals('b')){
b++;
}else if (put.equals('c')){
c++;
}else if (put.equals('d')){
d++;
}else{
e++;
}
}
System.out.println("a("+a+")");
System.out.println("b("+b+")");
System.out.println("c("+c+")");
System.out.println("d("+d+")");
System.out.println("e("+e+")");
}
}
(put.equals('a')){
a++;
}else if (put.equals('b')){
b++;
}else if (put.equals('c')){
c++;
}else if (put.equals('d')){
d++;
}else{
e++;
}
}
System.out.println("a("+a+")");
System.out.println("b("+b+")");
System.out.println("c("+c+")");
System.out.println("d("+d+")");
System.out.println("e("+e+")");
}
}