Map
1.1概述
-
Map:双列集合的顶层接口
-
Map:描述的就是一个数据(key)到另一个数据(value)的对应关系
-
一个数据(key):就是有规律的,容易记忆的,简单的一个数据
-
一个数据(value):没有规律的,不容易记忆的,复杂的一个数据
-
大多数都是根据key来寻找value
-
-
Map的特点:
-
Key(键)是唯一的
-
Value(值)不是唯一的
-
-
Map和Collection的区别:
-
Map是双列集合
-
Collection是单列集合
-
Map的键是唯一的,Collection中的Set子接口中的元素是唯一的
-
Map的所有操作是针对《键》有效,Collection中的set子接口中的操作针对《元素》有效
-
1.2Map中的常用方法
-
增加键值对:
-
put(K key, V value)
-
-
删除方法:
-
根据给定的键,删除对应的键值对:
-
remove (K key)
-
清空集合:clear()
-
-
-
获取方法:
-
获取集合的大小:size()
-
获取键对应的值,根据给定的键,获取对应的值:V get(K key)
-
-
判断方法:
-
判断集合中是否存在某个键:containsKey(Object obj)
-
判断集合中是否存在某个值:containsValue(Object obj)
-
-
修改方法:
-
根据给定的键,修改对应的值:put(K key, V value)
-
如果在集合中已经存在key这个键,那么使用put方法,就是修改其对应的值
-
如果集合中不存在key这个键,那么使用put方法,就是在集合中增加了一个键值对
-
-
代码示例:
import java.util.HashMap;
import java.util.Map;
/**
*Map中的常用方法
*/
public class Simple01 {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap();
map.put("a", 1);
map.put("b", 2);
map.put("c", 3);
map.put("c", 4);
System.out.println(map);
map.remove("a");
System.out.println(map);
map.clear();
System.out.println(map);
map.put("a", 1);
map.put("b", 2);
map.put("c", 3);
map.put("d", 4);
System.out.println(map.size());
Integer value = map.get("c");
System.out.println(value);
boolean b = map.containsKey("bb");
System.out.println(b);
boolean b1 = map.containsValue(4);
System.out.println(b1);
map.put("a", 11);
System.out.println(map.get("a"));
map.put("aa", 111);
System.out.println(map);
}
}
1.3 Map集合的第一种遍历思路【熟练掌握】
-
获取Map集合中的所有键,放到一个Set集合中,遍历该Set集合,获取到每一个键,根据键再来获取对应的值。【根据键获取值】
-
获取Map集合中的所有键并存入Set
-
Set<K> keySet() //k是你map中键的类型,Set<String> set = map.keySet();
-
遍历Set集合的两种方法:
-
迭代器
-
增强for循环
-
-
拿到每个键之后,获取对应的值 V get(K key)
-
特点: 获取了所有的键的集合之后,仍然要依赖原来的Map集合
代码示例:
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
* Map集合的第一种遍历思路【熟练掌握】
*/
public class Simple02 {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap();
map.put("aaa", 111);
map.put("bbb", 222);
map.put("ccc", 333);
map.put("ddd", 444);
System.out.println(map);
// test1(map);//第一种遍历思路的第一种遍历方式迭代器(map)
test2(map);// 第一种遍历思路的第二种遍历方式增强for(map)
}
// 第一种遍历思路的第一种遍历方式迭代器(map)
public static void test1(Map<String, Integer> map) {
Set<String> set = map.keySet();
Iterator<String> it = set.iterator();
while (it.hasNext()) {
String key = it.next();
System.out.println("key是:" + key + "---value是:" + map.get(key));
}
}
// 第一种遍历思路的第二种遍历方式增强for(map)
public static void test2(Map<String, Integer> map) {
Set<String> set = map.keySet();
for (String key : set) {
System.out.println("key是:" + key + "---value是:" + map.get(key));
}
}
}
1.4 Map集合的第二种遍历思路【熟练掌握】
-
获取Map集合中的所有键值对对象(Entry)到Set集合中,遍历Set集合,拿到的是每个键值对对象(Entry),从这个对象中分别获取键和值【根据键值对对象获取键和值】
-
根据Map集合获取所有的键值对对象,到一个Set集合中
-
Set<Map.Entry<K, V>> entrySet() Set<Map.Entry<String, String>> set = map.entrySet();
-
遍历Set集合,两种遍历方式
-
迭代器
-
增强for循环
-
-
获取到某个键值对对象
-
Entry是Map接口中的内部接口,访问的方式:Map.Entry
-
Entry:入口、条目、登记记录
-
Entry的常用方法:
-
getKey()获取当前键值对对象的键
-
getValue()获取当前键值对对象的值
-
-
代码示例:
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
* Map集合的第二种遍历思路【熟练掌握】
*/
public class Simple03 {
public static void main(String[] args) {
Map<String, String> map = new HashMap<>();
map.put("username", "zhangsan");
map.put("password", "123456");
map.put("nickname", "miaomi");
System.out.println(map);
test1(map)
test2(map);
}
//迭代器遍历Set集合
public static void test1(Map<String, String> map) {
Set<Map.Entry<String, String>> set = map.entrySet();
System.out.println(set);
Iterator<Map.Entry<String, String>> iterator = set.iterator();
while (iterator.hasNext()) {
Map.Entry<String, String> next = iterator.next();
String key = next.getKey();
String value = next.getValue();
System.out.println("键是:" + key + "---值是:" + value);
}
}
// 增强for循环遍历Set(map)
public static void test2(Map<String, String> map) {
Set<Map.Entry<String, String>> set = map.entrySet();
for (Map.Entry<String, String> st : set) {
System.out.println("键是:" + st.getKey() + "----值是:" + st.getValue());
}
}
}
1.5 HashMap
HashMap 的底层实现方式为哈希表,是 HashSet 的实现原理。
-
就是Map集合使用哈希表的存储方式的一种实现类
-
HashMap存储的是jdk中提供的类型的键,就可以直接保证键的唯一性
-
HashMap中存储的键,是自定义类型(比如下方代码Person),无法保证键的唯一性,原因:虽然都是zhangsan对象,但是这些对象并不是相同的对象,这些对象的哈希值计算结果各不相同,就说明一定不是相同的对象,所以无法保证键的唯一,重写hashCode和equals方法说明:HashMap的键的唯一性和HashSet的元素的唯一性,保证方式都一样
-
HashMap和HashSet的关系:
-
HashSet是由HashMap实现出来的,HashSet就是HashMap的键的那一列
-
将HashMap中的值的那一列隐藏掉,就变成了HashSet
-
-
示例代码:
-
import java.util.HashMap; import java.util.Objects; /** * HashMap; */ public class Simple04 { public static void main(String[] args) { HashMap<Person, String> hm = new HashMap<>(); hm.put(new Person("张三", 23), "北京"); hm.put(new Person("张三", 23), "上海"); hm.put(new Person("张三", 23), "广州"); System.out.println(hm); test1_HashMap存储jdk的键(); } private static void test1_HashMap存储jdk的键() { HashMap<String, Integer> hm = new HashMap<>(); hm.put("abc", 1); hm.put("abc", 3); hm.put("ab", 2); hm.put("ab", 4); System.out.println(); System.out.println("*******************"); System.out.println(); System.out.println(hm); } } class Person { String name; int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Person person = (Person) o; return age == person.age && Objects.equals(name, person.name); } @Override public int hashCode() { return Objects.hash(name, age); } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
1.6 LinkedHashMap
-
是HashMap的一个子类
-
实现原理哈希表+链表
-
和HashMap不同之处:具有可预知的迭代顺序,存储键值对的顺序和遍历集合时取出键值对的顺序一致。
-
代码示例:
-
import java.util.LinkedHashMap; /** * LinkedHashMap */ public class Simple05 { public static void main(String[] args) { LinkedHashMap<String, Integer> lhm = new LinkedHashMap<>(); lhm.put("aa", 3); lhm.put("bb", 3); lhm.put("cc", 2); lhm.put("dd", 4); System.out.println(lhm); } }
1.7 HashMap和Hashtable的关系
-
HashMap和Hashtable都是用于存储键和值的对应关系,都是Map的实现类,都是使用哈希表的方式存储。
-
不同点:
-
版本不同,Hashtable是jdk1.0版本出现的,HashMap是jdk1.2版本出现的
-
线程安全性不同,Hashtable是线程安全的,HashMap是线程不安全的
-
Hashtable不能存储null键null值,HashMap可以存储null键null值
-
-
代码示例:
-
import java.util.HashMap; import java.util.Hashtable; /** * HashMap和Hashtable的关系 */ public class Simple06 { public static void main(String[] args) { HashMap<String, Integer> hm = new HashMap<>(); hm.put(null, 0);//键可以存null值 hm.put("1", null);//值可以存null值 // hm.put(null, null);//键值可以存null值 System.out.println(hm); test1_Hashtable存储null键null值(); } public static void test1_Hashtable存储null键null值() { //Hashtable 不可以存储null键值 Hashtable<String, Integer> ht = new Hashtable<>(); ht.put("abc", 3); ht.put(null, 0); ht.put("", null); ht.put(null, null); System.out.println(ht); } }
Collections集合工具类
-
java.utils.Collections是集合工具类,用来对集合进行操作。工具类的使用方式是类名.方法 比如Collections.sort(list)
-
常用方法如下:
-
max
-
min
-
addAll
-
reverse
-
shuffle
-
public static void test1() { ArrayList<Integer> list = new ArrayList<>(); list.add(11); list.add(33); list.add(55); System.out.println(Collections.max(list)); System.out.println(Collections.min(list)); Collections.addAll(list, 1, 2, 3, 4, 5, 6, 7, 8); System.out.println(list); Collections.reverse(list); System.out.println(list); Collections.shuffle(list); System.out.println(list); }
-
sort 接口实现
-
public class CollectionsUtil { public static void main(String[] args) { test2(); } public static void test2() { /* * java.utils.Collections是集合工具类,用来对集合进行操作。 * 工具类的使用方式是类名.方法 比如Collections.sort(list) * 注意被排序的集合里面存储的元素必须要实现Comparable接口,并重写接口中 * 的Compare To 定义排序的规则 * 像案例中的String ,Integer 默认已经实现了Comparable接口 * 但是如果是自定义类就需要手动实现Comparable接口并指定泛型。 * Compare To 定义排序的规则: * this.属性 - 参数.属性 :升序 ,反之降序 * * */ ArrayList<Integer> list1 = new ArrayList<>(); Collections.addAll(list1, 1, 44, 55, 22, 12, -45, 0); Collections.sort(list1); System.out.println(list1);// 默认升序 ArrayList<String> list2 = new ArrayList<>(); Collections.addAll(list2, "a", "b", "aa", "c", "bb"); Collections.sort(list2); System.out.println(list2);// 默认升序 ArrayList<Animal> list3 = new ArrayList<>(); list3.add(new Animal("佩奇", 3)); list3.add(new Animal("艾米丽", 5)); list3.add(new Animal("苏西", 2)); Collections.sort(list3); System.out.println(list3); } } class Animal implements Comparable<Animal> { private String name; private int age; public Animal(String name, int age) { this.name = name; this.age = age; } public Animal() { } 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; } // 这里不需要重写hashcode 和 equals 方法,因为我们没用set; @Override public String toString() { return "Animal{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override public int compareTo(Animal o) { // return this.getAge() - o.getAge();// 按年龄升序 return o.getAge() - this.getAge();// 按年龄降序 } }
-
sort 匿名内部类
-
public class CollectionsUtil { public static void main(String[] args) { test3(); } public static void test3() { /* * Comparator 和 Comparable区别 * Comparable区别是自己和别人(参数)比较,需要实现Comparable接口,重写ComparaeTo方法 * Comparator相当于找一个第三方的裁判,比较2个参数的大小,需要使用匿名内部类 * */ ArrayList<Animal> list4 = new ArrayList<>(); list4.add(new Animal("a佩奇", 3)); list4.add(new Animal("b艾米丽", 5)); list4.add(new Animal("a苏西", 5)); // Collections.sort(list4, new Comparator<Animal>() { // @Override // public int compare(Animal o1, Animal o2) { // return o1.getAge() - o2.getAge(); // } // }); Collections.sort(list4, new Comparator<Animal>() { @Override public int compare(Animal o1, Animal o2) { // 按年龄排序 int result = o1.getAge() - o2.getAge(); // 如果年龄相同按姓名排序 if (result == 0) { result = o1.getName().charAt(0) - o2.getName().charAt(0); } return result; } }); System.out.println(list4); } } class Animal { private String name; private int age; public Animal(String name, int age) { this.name = name; this.age = age; } public Animal() { } 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; } // 这里不需要重写hashcode 和 equals 方法,因为我们没用set; @Override public String toString() { return "Animal{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
-