Map
- 将键映射到值的对象
- 一个映射不能包含重复的键
- 每个键最多只能映射到一个值
Map 与 Collection 接口的不同
- Map 是双列的, Collection 是单列的
- Map 是键唯一, Collection 的子体系Set是唯一的
- Map 集合的数据结构值针对键有效, 跟值无关; Collection集合的数据结构是针对元素有效
Map 方法
- V put(K key, V value) 添加键和值, 成功返回null, 覆盖重复key值, 则返回被覆盖的Value值
- V remove(Object key) 通过key删除元素, 删除成功则返回Value值
- boolean containsKey(Object key) Map 中是否包含Key值
- boolean containsValue(Object value) Map 中是否包含Value值
- boolean isEmpty() Map 是否为空
- clear() 清空Map
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
public class Demo1_Map {
public static void main(String[] args) {
// Demo1();
Map<String, Integer> hashMap = new HashMap<>();
hashMap.put("小明", 18);
hashMap.put("小红", 19);
hashMap.put("小王", 20);
System.out.println(hashMap);
Integer i = hashMap.remove("小王");
System.out.println(i);
System.out.println(hashMap);
System.out.println(hashMap.containsKey("小明"));
System.out.println(hashMap.containsValue(19));
System.out.println(hashMap.isEmpty());
Collection<Integer> v = hashMap.values();
System.out.println(v);
hashMap.clear();
System.out.println(hashMap.size());
}
private static void Demo1() {
Map<String,Integer> map = new HashMap<>();
Integer i1 = map.put("s1",12);
Integer i2 = map.put("s2",22);
Integer i3 = map.put("s3",33);
Integer i4 = map.put("s3",34);
Integer i5 = map.put("s5",35);
Integer i6 = map.put("s6",35);
System.out.println(map);
System.out.println(i4);
System.out.println(i5);
System.out.println(i6);
}
}
Map 根据键获取值
import java.util.HashMap;
public class Demo2_Iterator {
public static void main(String[] args) {
HashMap<String, Integer> hashMap = new HashMap<>();
hashMap.put("a", 100);
hashMap.put("b",90);
hashMap.put("c",98);
for(String s:hashMap.keySet()){
System.out.println(s + "="+ hashMap.get(s));
}
}
}
Map 的键值对, 来获取Map中的Key 与 Value
import java.util.HashMap;
import java.util.Map;
public class Demo3_Iterator {
public static void main(String[] args) {
HashMap<String, Integer> hashMap = new HashMap<>();
hashMap.put("a", 90);
hashMap.put("b",95);
hashMap.put("c",98);
for(Map.Entry<String,Integer> single: hashMap.entrySet()){
System.out.println(single.getKey() + " "+ single.getValue());
}
}
}
HashMap 存入Student类和String时, 重写 hashCode 和 equals方法
import lombok.Getter;
import lombok.Setter;
import java.util.Objects;
public class Student {
public Student(){}
public Student(String name, int age){
this.name = name;
this.age = age;
}
@Getter
@Setter
private String name;
@Getter
@Setter
private int age;
@Override
public String toString() {
return "Student "+this.name+this.age;
}
@Override public int hashCode() {
return Objects.hash(name, age);
}
@Override
public boolean equals(Object obj) {
Student s = (Student) obj;
return this.name == s.name && this.age == s.age;
}
}
import com.lizicai.bean.Student;
import java.util.HashMap;
public class Demo4_HashMap {
public static void main(String[] args) {
HashMap<Student, String> hashMap = new HashMap<>();
hashMap.put(new Student("小明",23), "上海");
hashMap.put(new Student("小明",23), "北京");
hashMap.put(new Student("小王",26), "北京");
hashMap.put(new Student("莱昂纳多",28), "美国");
System.out.println(hashMap);
}
}
LinkedHashMap
import java.util.LinkedHashMap;
public class Demo5_LinkedHashMap {
public static void main(String[] args) {
LinkedHashMap<String,Integer> linkedHashMap = new LinkedHashMap<>();
linkedHashMap.put("a", 20);
linkedHashMap.put("b", 20);
linkedHashMap.put("c", 20);
System.out.println(linkedHashMap);
}
}
TreeMap 必须实现 Comparable 接口, 2种方式
方式一在bean类中实现Comparable 接口
import lombok.Getter;
import lombok.Setter;
import java.util.Objects;
public class Student implements Comparable<Student>{
public Student(){}
public Student(String name, int age){
this.name = name;
this.age = age;
}
@Getter
@Setter
private String name;
@Getter
@Setter
private int age;
@Override
public String toString() {
return "Student "+this.name+this.age;
}
@Override public int hashCode() {
return Objects.hash(name, age);
}
@Override
public boolean equals(Object obj) {
Student s = (Student) obj;
return this.name == s.name && this.age == s.age;
}
@Override
public int compareTo(Student o) {
int numName = this.name.compareTo(o.name);
int numAge = numName == 0 ? this.age-o.age : numName;
return numAge;
}
}
public class Demo6_TreeMap {
public static void main(String[] args) {
// Demo1();
TreeMap<Student, String> treeMap = new TreeMap<>();
treeMap.put(new Student("ab",23), "上海");
treeMap.put(new Student("ab",23), "北京");
treeMap.put(new Student("ac",26), "北京");
treeMap.put(new Student("abc",28), "美国");
System.out.println(treeMap);
}
}
方式二, 在创建TreeMap时实现 Comparator 接口
public static void main(String[] args) {
TreeMap<Student, String> treeMap = new TreeMap<>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
int numName = o1.getName().compareTo(o2.getName());
int numAge = numName == 0 ? o1.getAge()-o2.getAge() : numName;
return numAge;
}
});
treeMap.put(new Student("ab",23), "上海");
treeMap.put(new Student("ab",23), "北京");
treeMap.put(new Student("ac",26), "北京");
treeMap.put(new Student("abc",28), "美国");
System.out.println(treeMap);
}
练习, 字符串 aaabbbccccfgkj 统计字母出现次数
- 字母在Map里Key 没有, 由存入key,1, 有则存key, value+1
import java.util.HashMap;
import java.util.Map;
public class Demo7_HashMap {
public static void main(String[] args) {
HashMap<Character, Integer> hashMap = new HashMap<>();
String str = "aaabbbbccccd";
char[] cArray = str.toCharArray();
for(char c : cArray){
if( ! hashMap.containsKey(c)){
hashMap.put(c,1);
} else {
hashMap.put(c, hashMap.get(c)+1);
}
}
for(Map.Entry<Character,Integer> ci:hashMap.entrySet()){
System.out.println(ci.getKey() + "=" + ci.getValue() );
}
}
}
练习 HashMap 嵌套 HashMap
import lombok.Getter;
import lombok.Setter;
import java.util.Objects;
public class Student implements Comparable<Student>{
public Student(){}
public Student(String name, int age){
this.name = name;
this.age = age;
}
@Getter
@Setter
private String name;
@Getter
@Setter
private int age;
@Override
public String toString() {
return "Student "+this.name+this.age;
}
@Override public int hashCode() {
return Objects.hash(name, age);
}
@Override
public boolean equals(Object obj) {
Student s = (Student) obj;
return this.name == s.name && this.age == s.age;
}
import com.lizicai.bean.Student;
import java.util.HashMap;
import java.util.Map;
public class Demo8_HashMapHashMap {
public static void main(String[] args) {
HashMap<Student, String> hashMap1 = new HashMap<>();
hashMap1.put(new Student("小明",23), "上海");
hashMap1.put(new Student("小王",26), "北京");
hashMap1.put(new Student("莱昂纳多",28), "美国");
HashMap<Student, String> hashMap2 = new HashMap<>();
hashMap2.put(new Student("小明",23), "上海");
hashMap2.put(new Student("小王",26), "北京");
hashMap2.put(new Student("莱昂纳多",29), "美国");
HashMap<HashMap<Student,String>,String > hashMap = new HashMap<>();
hashMap.put(hashMap1,"班级1");
hashMap.put(hashMap2,"班级2");
for(Map.Entry<HashMap<Student,String>, String> HH : hashMap.entrySet()){
for(Map.Entry<Student,String> HHS : HH.getKey().entrySet()){
System.out.println(HHS.getKey() + HHS.getValue()+HH.getValue());
}
}
System.out.println(hashMap);
}
}
HashMap 和 Hashtable 区别
共同点
- 都是双链集合
区别
- HashMap 是线程不安全的, 效率高JDK 1.2 版本
- Hashtable 是线程安全的, 效率低, JDK 1.0 版本
- HashMap 可以存储null 键 和 null 值
- Hashtable 不可以存储null 键 及 null 值
import java.util.HashMap;
import java.util.Hashtable;
public class Demo9_HashMapHashtable {
public static void main(String[] args) {
HashMap<String, Integer> hashMap = new HashMap<>();
hashMap.put(null, 10);
hashMap.put("a", null);
System.out.println(hashMap);
Hashtable<String, Integer> hashtable = new Hashtable<>();
hashtable.put(null, 10);
hashtable.put("a", null);
System.out.println(hashtable);
}
}
Collections 中的方法
- static <T extends Comparable<? super T» void sort(List
list) 排序 - static
int binarySearch(List<? extends Comparable<? super T» list, T key) 二分查找 - static <T extends Object & Comparable<? super T» T max(Collection<? extends T> coll) 返回最大值
- static void reverse(List list) 反转列表
- static void shuffle(List list) list 序列洗牌
private static void Demo5() {
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("d");
arrayList.add("a");
arrayList.add("a");
arrayList.add("b");
arrayList.add("c");
arrayList.add("f");
System.out.println(arrayList);
Collections.shuffle(arrayList);
System.out.println(arrayList);
}
private static void Demo4() {
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("d");
arrayList.add("a");
arrayList.add("a");
arrayList.add("b");
arrayList.add("c");
arrayList.add("f");
System.out.println(arrayList);
Collections.reverse(arrayList);
System.out.println(arrayList);
}
private static void Demo3() {
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("d");
arrayList.add("a");
arrayList.add("a");
arrayList.add("b");
arrayList.add("c");
arrayList.add("f");
String max = Collections.max(arrayList);
System.out.println(max);
}
private static void Demo2() {
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("d");
arrayList.add("a");
arrayList.add("a");
arrayList.add("b");
arrayList.add("c");
arrayList.add("a");
Collections.sort(arrayList);
System.out.println(arrayList);
int index = Collections.binarySearch(arrayList, "b");
System.out.println(index);
System.out.println(Collections.binarySearch(arrayList,"o"));
}
private static void Demo1() {
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("d");
arrayList.add("a");
arrayList.add("a");
arrayList.add("b");
arrayList.add("c");
arrayList.add("a");
System.out.println(arrayList);
Collections.sort(arrayList);
System.out.println(arrayList);
}
练习, 54 张牌, 每人17张, 剩下3张, 打印每个人牌和底牌
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
public class Demo2_Collections {
public static void main(String[] args) {
String[] nu = {"2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"};
String[] color = { "♠️", "♥️", "♦️", "♣️"};
ArrayList<String> arrayList = new ArrayList<>();
for(String nuStr : nu){
for(String colorStr : color){
arrayList.add(nuStr + colorStr);
}
}
arrayList.add("Big King");
arrayList.add("Small King");
for(int i=0;i<3;i++){
Collections.shuffle(arrayList);
}
System.out.println(arrayList);
ArrayList<String> list1 = new ArrayList<>();
ArrayList<String> list2 = new ArrayList<>();
ArrayList<String> list3 = new ArrayList<>();
ArrayList<String> list4 = new ArrayList<>();
Scanner sc = new Scanner(System.in);
for(int i=0;i<53;i++){
if(i >= 50 ){
list4.add(arrayList.get(i));
}
else if( i % 3 == 0){
list1.add(arrayList.get(i));
} else if( i % 3 == 1) {
list2.add(arrayList.get(i));
} else if( i % 3 ==2 ){
list3.add(arrayList.get(i));
}
}
System.out.println(list4);
System.out.println(list1);
System.out.println(list2);
System.out.println(list3);
}
}
练习使用 HashMap 模拟一副牌
- 用HashMap 的 Key 生成arraylist来洗牌
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.TreeMap;
public class Demo3_Collections {
public static void main(String[] args) {
HashMap<Integer, String> poker = new HashMap<>();
String[] nu = { "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A","2"};
String[] color = { "♠️", "♥️", "♦️", "♣️"};
int count = 0;
ArrayList<Integer> pokerIndex = new ArrayList<>();
for(String nuStr : nu){
for(String colorStr : color){
poker.put(count, (colorStr + nuStr));
pokerIndex.add(count);
count++;
}
}
poker.put(count, "Small King");
pokerIndex.add(count);
count++;
poker.put(count, "Big King");
pokerIndex.add(count);
TreeMap<Integer, String> gaojin = new TreeMap<>();
TreeMap<Integer, String> jp = new TreeMap<>();
TreeMap<Integer, String> tiger = new TreeMap<>();
TreeMap<Integer, String> dipai = new TreeMap<>();
System.out.println(pokerIndex.size());
Collections.shuffle(pokerIndex);
System.out.println(pokerIndex);
for(int i=0;i< pokerIndex.size(); i++){
int index = pokerIndex.get(i);
if(i > 50){
dipai.put( index , poker.get( index));
} else if ( i % 3 == 0){
gaojin.put( index, poker.get(index ));
} else if (i % 3 == 1){
jp.put( index , poker.get( index ));
} else if (i % 3 == 2){
tiger.put( index, poker.get( index ));
}
}
System.out.println(gaojin);
System.out.println(jp);
System.out.println(tiger);
System.out.println(dipai);
}
}
? Super E 情况
- TreeSet TreeMap 会调用
import lombok.Getter;
import lombok.Setter;
import java.util.Objects;
public class Student implements Comparable<Student>{
public Student(){}
public Student(String name, int age){
this.name = name;
this.age = age;
}
@Getter
@Setter
private String name;
@Getter
@Setter
private int age;
@Override
public String toString() {
return "Student "+this.name+this.age;
}
@Override public int hashCode() {
return Objects.hash(name, age);
}
@Override
public boolean equals(Object obj) {
Student s = (Student) obj;
return this.name == s.name && this.age == s.age;
}
@Override
public int compareTo(Student o) {
int numName = this.name.compareTo(o.name);
int numAge = numName == 0 ? this.age-o.age : numName;
return numAge;
}
}
public class BaseStudent extends Student{
public BaseStudent(){}
public BaseStudent(String name, int age){
super(name, age);
}
}
import com.lizicai.bean.BaseStudent;
import com.lizicai.bean.Student;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.TreeSet;
public class Demo4_Generic {
public static void main(String[] args) {
// Demo1();
TreeSet<Student> treeSet = new TreeSet<>(new CompareByAge());
treeSet.add(new Student("小明",22));
treeSet.add(new Student("小红",22));
treeSet.add(new Student("小王",22));
System.out.println(treeSet);
TreeSet<BaseStudent> treeSet2 = new TreeSet<>(new CompareByAge());
treeSet2.add(new BaseStudent("小明",22));
treeSet2.add(new BaseStudent("小红",22));
treeSet2.add(new BaseStudent("小王",22));
System.out.println(treeSet2);
}
private static void Demo1() {
ArrayList<Student> arrayList = new ArrayList<>();
arrayList.add(new Student("小明",22));
arrayList.add(new Student("小红",22));
arrayList.add(new Student("小王",22));
ArrayList<BaseStudent> arrayList2 = new ArrayList<>();
arrayList2.add(new BaseStudent("小明",22));
arrayList2.add(new BaseStudent("小红",22));
arrayList2.add(new BaseStudent("小王",22));
arrayList.addAll(arrayList2);
System.out.println(arrayList);
}
}
class CompareByAge implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
int num = o1.getAge() - o2.getAge();
int numName = num == 0 ? o1.getName().compareTo(o2.getName()): num;
return numName;
}
}
Collection
List 存取有序, 有索引, 可重复
- ArrayList
- 底层数组实现的, 线程不安全, 查找修改快, 增删慢
- LinkedList
- 底层是链表实现的, 线程不安全, 查找慢, 增删快
- Vetor
- 底层数组实现的, 线程安全, 查找修改增删都慢
如果查找修改多用ArrayList, 增和删多用LinkedList, 如果都多用ArrayList
Set 存取无序, 无索引, 不可重复
- HashSet
- 底层哈希算法实现的
- LinkedHashSet
- 底层是链表, 但是也可以保证元素唯一, 和HashSet 原理一样
- TreeSet
- 底层是二叉树实现
开发的时候不需要对存储的元素排序, 大多用HashSet TreeSet 比较的2种方式要记住
Map 存取
- HashMap 底层哈希算法, 针对键的
- LinkedHashMap 底层是链表
- TreeMap 底层是二叉树实现
双链集合优先考虑TreeMap