JavaSE-集合(Map)
Map
特点:key 唯一,无序
基本API
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MyMap {
public static void main(String[] args) {
/**
* Map<K, V>:----key----value "键值对"
* API
*
* 增加:put() putAll()
* 删除:clear() remove()
* 修改:replace()
* 查询:size() get() entrySet() keySet() values()
* 判断:equals() isEmpty() containsValue() containsKey()
*/
Map<Integer, String> map = new HashMap<Integer, String>();
map.put(0, "hello");// 存入的键值对都是由映射关系的
map.put(15, "java");
map.put(18, "python");
map.put(5, "java");
map.put(0, "php");
System.out.println(map.keySet()); //=> [0, 18, 5, 15],返回此映射中包含的键的Set视图。
System.out.println(map.entrySet()); //=> [0=php, 18=python, 5=java, 15=java],返回此映射中包含的映射的Set视图。
System.out.println(map.values()); //=> [php, python, java, java],返回此映射中包含的值的Collection视图。
System.out.println(map.containsKey(0)); //=> true
System.out.println(map.containsValue("java")); //=> true
System.out.println(map.replace(0, "Json")); //=> "php",执行key进行更新操作,返回替换前的数据
System.out.println(map.replace(0, "js", "Javascript")); //=> false,对执行的映射进行更新操作成功返回true,否则返回false
System.out.println(map); //=> {0=php, 18=python, 5=java, 15=java},特点:key唯一,无序
System.out.println(map.size()); //=> 4
System.out.println(map.get(0));
// 遍历
Set<Integer> keySet = map.keySet();
for (Integer o :
keySet) {
System.out.println(map.get(o));
}
System.out.println("------------------");
Collection<String> keySet2 = map.values();
for (String o :
keySet2) {
System.out.println(o);
}
// 内部接口作为泛型
// entrySet() 方法返回的是Set 类型,有泛型,泛型为:Entry 类型--->是Map 接口中的内部接口
// 这个接口的泛型又有两个类型Integer ,String
System.out.println("------------------");
Set<Map.Entry<Integer, String>> entries = map.entrySet();
for (Map.Entry<Integer, String> o :
entries) {
System.out.println(o.getKey() + "-----" + o.getValue());
}
}
}
HashMap 实现类
特点:key 唯一,无序
基本API
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MyMap {
public static void main(String[] args) {
/**
* Map<K, V>:----key----value "键值对"
* API
*
* 增加:put() putAll()
* 删除:clear() remove()
* 修改:replace()
* 查询:size() get() entrySet() keySet() values()
* 判断:equals() isEmpty() containsValue() containsKey()
*/
Map<Integer, String> map = new HashMap<Integer, String>();
map.put(0, "hello");// 存入的键值对都是由映射关系的
map.put(15, "java");
map.put(18, "python");
map.put(5, "java");
map.put(0, "php");
System.out.println(map.keySet()); //=> [0, 18, 5, 15],返回此映射中包含的键的Set视图。
System.out.println(map.entrySet()); //=> [0=php, 18=python, 5=java, 15=java],返回此映射中包含的映射的Set视图。
System.out.println(map.values()); //=> [php, python, java, java],返回此映射中包含的值的Collection视图。
System.out.println(map.containsKey(0)); //=> true
System.out.println(map.containsValue("java")); //=> true
System.out.println(map.replace(0, "Json")); //=> "php",执行key进行更新操作,返回替换前的数据
System.out.println(map.replace(0, "js", "Javascript")); //=> false,对执行的映射进行更新操作成功返回true,否则返回false
System.out.println(map); //=> {0=php, 18=python, 5=java, 15=java},特点:key唯一,无序
System.out.println(map.size()); //=> 4
System.out.println(map.get(0));
// 遍历
Set<Integer> keySet = map.keySet();
for (Integer o :
keySet) {
System.out.println(map.get(o));
}
System.out.println("------------------");
Collection<String> keySet2 = map.values();
for (String o :
keySet2) {
System.out.println(o);
}
// 内部接口作为泛型
// entrySet() 方法返回的是Set 类型,有泛型,泛型为:Entry 类型--->是Map 接口中的内部接口
// 这个接口的泛型又有两个类型Integer ,String
System.out.println("------------------");
Set<Map.Entry<Integer, String>> entries = map.entrySet();
for (Map.Entry<Integer, String> o :
entries) {
System.out.println(o.getKey() + "-----" + o.getValue());
}
}
}
加入要使用引用类型作为key 要怎么做?
必须重写hashCode()和equals()方法
import java.util.*;
class Test{
public int age;
public String name;
public Test(int age, String name) {
this.age = age;
this.name = name;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Test)) return false;
Test test = (Test) o;
return age == test.age && name.equals(test.name);
}
@Override
public int hashCode() {
return Objects.hash(age, name);
}
@Override
public String toString() {
return "Test{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
}
public class MyMap {
public static void main(String[] args) {
/**
* 使用引用类型作为 key
* 必须重写 hashCode()和 equals()
*/
Map<Test, String> map2 = new HashMap<Test, String>();
map2.put(new Test(12,"xiaoming"),"1");
map2.put(new Test(12,"xiaoming"),"1");
map2.put(new Test(13,"xiaoming"),"1");
System.out.println("--------------------");
System.out.println(map2); //=> {Test{age=13, name='xiaoming'}=1, Test{age=12, name='xiaoming'}=1}
System.out.println(map2.size()); //=> 2
}
}
源码分析:
public class MyMap {
public static void main(String[] args) {
Map<Integer, String> map = new HashMap<Integer, String>();
map.put(0, "hello");
System.out.println(map);
}
}
存储方式是主数组 + 链表
底层构造器与put 方法
public class HashMap<K,V> extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable {
static final float DEFAULT_LOAD_FACTOR = 0.75f; // 装填因子
// 这就是底层储存用的主数组
// 这个数组的类型是 Node<K,V> 类对象
transient Node<K,V>[] table