1.Map集合概述和特点
a:概述
(1)将键映射到值的对象
(2)一个映射不能包含重复的键
(3)每个键最多只能映射一个值
b:Map接口和Collection接口的不同
(1)Map是双列的,Collection是单列的
(2)Map的键唯一,Collection的子体系Set是唯一的
(3)Map集合的数据结构只针对键有效,跟值无关;collection集合的数据结构是针对元素有效
2.Map集合的方法
/**
* (1).put方法
V put(K key, V value)
如果映射先前包含了密钥的映射,则旧值将被指定的值替换。
(映射m被认为包含关键字的映射k当且仅当m.containsKey(k)将返回true )。
参数 :
key - 指定值与之关联的键
value - 与指定键相关联的值
结果 :
前一个值与key相关联 ,或null,如果没有key的映射。 (A null返回也可以表示该地图以前关联的null与key ,如果实现支持null的值)
异常
UnsupportedOperationException -如果 put操作不受此地图支持
ClassCastException - 如果指定的键或值的类阻止它存储在此映射中
NullPointerException - 如果指定的键或值为空,并且此映射不允许空值或值
IllegalArgumentException - 如果指定键或值的某些属性阻止其存储在此映射中
package com.guada.map;
import java.util.HashMap;
import java.util.Map;
public class Demo1_Map {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<String, Integer>();
System.out.println(map.containsKey("zs")); //false
System.out.println(map.put("zs", 23)); //null
System.out.println(map.containsKey("zs"));//true
map.put("ww", 25);
Integer i1 = map.put("ls", 24);//因为put方法的返回值是V,可以用指定类型的变量进行接收
System.out.println(i1);//null
System.out.println(map); //{ww=25, ls=24, zs=23}
Integer i2 = map.put("ls", 25); //将被覆盖的值返回
System.out.println(i2); //24
System.out.println(map); //{ww=25, ls=25, zs=23} 键是唯一的
}
}
(2) /**
* 清空方法
* 1.clear
void clear()从该地图中删除所有的映射(可选操作)。 此操作返回后,地图将为空。
public class Demo1_Map {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("zs", 24);
System.out.println(map); //{zs=24}
map.clear();
System.out.println(map); //{}
}
}
(3)/**
* remove
V remove(Object key)如果存在(从可选的操作),从该地图中删除一个键的映射。
更正式地,如果该映射包含从关键字k到值v的映射,使得(keynull ? knull : key.equals(k)) ,该映射被去除。
(地图最多可以包含一个这样的映射。)
返回此地图先前相关联的密钥,或null如果映射包含该键的映射值。
如果此映射允许空值,那么null返回值并不一定表明此映射不包含该键的映射关系; 地图也可能显式地将密钥映射到null 。
一旦操作返回,该映射将不包含指定键的映射。
参数 :
key - 其映射将从地图中删除的密钥
结果 :
前一个值与 key相关联 ,或 null,如果没有 key的映射。
public class Demo1_Map {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("zs", 23);
map.put("ls", 24);
System.out.println(map);//{ls=24, zs=23}
System.out.println(map.remove("zs"));//23
System.out.println(map);//{ls=24}
}
}
(4)/**
*size
int size()返回此地图中键值映射的数量。 如果地图包含超过Integer.MAX_VALUE个元素,则返回Integer.MAX_VALUE 。
结果
该地图中键值映射的数量
isEmpty
boolean isEmpty()如果此地图不包含键值映射,则返回 true 。
结果 :
true:此映射不包含键值映射
public class Demo1_Map {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("zs", 23);
map.put("ls", 24);
System.out.println(map.size());//2
System.out.println(map.isEmpty());//false
}
}
**
(5)
containsKey
boolean containsKey(Object key)如果此映射包含指定键的映射,则返回true 。 更正式地,返回true当且仅当该地图包含关键字k的映射
参数 :
key - 要在此地图中存在的密钥要进行测试
结果 :
true如果此映射包含指定键的映射
containsValue
boolean containsValue(Object value)如果此映射将一个或多个键映射到指定的值,则返回true 。 对于Map接口的大多数实现,此操作对于地图大小可能需要时间线性。
参数 :
value - 要在此地图中存在的值要进行测试
结果 :
true如果该地图将一个或多个键映射到指定的值
public class Demo1_Map {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("zs", 23);
map.put("ls", 24);
System.out.println(map.containsKey("zs"));//true
System.out.println(map.containsValue(23));//true
}
}
(6)
V get(Object key)返回到指定键所映射的值,或null;
参数 :
key - 要返回其关联值的键
结果 :
指定键映射到的值,如果此映射不包含键的映射, null
void putAll(Map<? extends K,? extends V> m)
将指定地图的所有映射复制到此映射(可选操作)。
该呼叫的效果与从指定地图中的关键字k到值v的每个映射一次对该地图一次调用put(k, v)的效果相当。
如果在操作进行中修改了指定的地图,则此操作的行为是未定义的。
参数 :
m - 要存储在此地图中的映射
public class Demo1_Map {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("zs", 23);
map.put("ls", null);
System.out.println(map.get("zs"));// 23
System.out.println(map.get("ss"));// null
System.out.println(map.get("ls"));// null
Map<String, Integer> map1 = new HashMap<String, Integer>();
map1.putAll(map);
System.out.println(map1); //{zs=23, ls=null}
}
}
(7)
Set keySet()返回此地图中包含的键的Set视图。
结果 :
该地图中包含的键的集合视图
Collection values()返回此地图中包含的值的Collection视图。
结果:
该地图中包含的值的集合视图
public class Demo1_Map {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("zs", 23);
map.put("ls", null);
System.out.println(map.keySet()); //[ls, zs]
System.out.println(map.values()); //[null, 23]
}
}
(8)
Set<Map.Entry<K,V>> entrySet()返回此地图中包含的映射的Set视图。
结果:
该地图中包含的映射的集合视图
boolean equals(Object o)将指定的对象与此映射进行比较以获得相等性。
如果给定的对象也是一个地图,并且两个地图代表相同的映射,则返回true 。
更正式地,如果m1.entrySet().equals(m2.entrySet()) ,两个地图m1和m2代表相同的映射。 这
确保equals方法在Map接口的不同实现方面正常工作。
重写:
equals在类别 Object
参数 :
o - 要与此映射相等的对象进行比较
结果 :
true如果指定的对象等于此映射
public class Demo1_Map {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("zs", 23);
map.put("ls", null);
Map<String, Integer> map1 = new HashMap<String, Integer>();
map1.put("zs", 23);
map1.put("ls", null);
System.out.println(map.entrySet()); //[ls=null, zs=23]
System.out.println(map.equals(map1)); //true
}
}
(9)
public class Demo1_Map {
/**
map集合没有iterator方法,如何实现双列集合的迭代
*/
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("zs", 23);
map.put("ls", 24);
Set<String> keyset = map.keySet(); //获取map集合的键值集合
Iterator<String> it = keyset.iterator(); //获取迭代器
while (it.hasNext()) { //判断元素中是否有值
String key = it.next(); //获取每一个键
Integer value = map.get(key); //获取键映射的值
System.out.println(key+"="+value); //ls=24
//zs=23
}
Map<String, Integer> map1 = new HashMap<String, Integer>();
map1.put("zs", 23);
map1.put("ls", 24);
map1.put("ss", 24);
//使用增强for循环进行遍历
for (String keString : map1.keySet()) {
System.out.println(keString+"="+map1.get(keString));
}
}
}
(10)
map集合没有iterator方法,如何实现双列集合的迭代
第二种迭代的方法,根据键值对进行迭代
public class Demo1_Map {
public static void main(String[] args) {
Map<String, Integer> map1 = new HashMap<String, Integer>();
map1.put("zs", 23);
map1.put("ls", 24);
map1.put("ss", 24);
Set<Map.Entry<String, Integer>> entry = map1.entrySet(); //创建键值对队象entry,获取所有的键值对
Iterator<Map.Entry<String, Integer>> it = entry.iterator();
while(it.hasNext()){
Map.Entry<String, Integer> en = it.next();
System.out.println(en.getKey()+"="+en.getValue());
}
System.out.println("循环");
for (Entry<String, Integer> entry2 : entry) {
System.out.println(entry2.getKey()+"="+entry2.getValue());
}
}
}
(11)
public class Demo1_Map {
/**
键值是Student对象
*/
public static void main(String[] args) {
HashMap<Student, String> map = new HashMap<Student, String>();
map.put(new Student("zx",23), "上海");
map.put(new Student("zx",23), "广州"); //自定义对象要重写hashCode和equals方法
map.put(new Student("lx",23), "深圳"); //否则实现不了键值对映射的唯一性
System.out.println(map);
}
}
package com.guada.map;
public class Student {
private String name;
private int age;
public Student() {
super();
}
public Student(String name,int age) {
super();
this.age=age;
this.name=name;
}
//重写equals方法
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
public int getAge() {
return age;
}
//get set方法
public String getName() {
return name;
}
//重写hashCode方法
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
public void setAge(int age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
//重写toString方法
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
/compareTo方法重写
@Override
public int compareTo(Student o) {
int num = this.age - o.age; //以年龄为主要条件
return num == 0?this.name.compareTo(o.name):num;
}
}
(12)
package com.guada.map;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.TreeMap;
public class Demo1_Map {
/**
LinkedHashMap TreeMap
*/
public static void main(String[] args) {
TreeMap<Student, String> tm = new TreeMap<Student, String>(new Comparator<Student>() {
//传进来一个比较器
/*TreeMap(Comparator<? super K> comparator)
构造一个新的,空的树图,按照给定的比较器排序。*/
@Override
public int compare(Student o1, Student o2) {
int num = o1.getName().compareTo(o2.getName()); //以name为主要的比较
return num==0?o1.getAge()-o2.getAge():num;
}
});
tm.put(new Student("ss", 24), "上海");
tm.put(new Student("zs", 14), "上海");
tm.put(new Student("ls", 23), "上海");
System.out.println(tm);
lhmMapDemo();
tmMapDemo();
}
public static void tmMapDemo() {
TreeMap<Student, String> tm = new TreeMap<Student, String>();
tm.put(new Student("ss", 24), "上海");
tm.put(new Student("ss", 14), "上海");
tm.put(new Student("ss", 23), "上海");
System.out.println(tm); //需要重写 compare方法 //{Student [name=ss, age=14]=上海, Student [name=ss, age=23]=上海, Student [name=ss, age=24]=上海}
}
public static void lhmMapDemo() {
LinkedHashMap<String, Integer> lhm = new LinkedHashMap<String, Integer>();
lhm.put("zx", 23);
System.out.println(lhm); //{zx=23}
}
}
(13)
public class Demo1_Map {
/**
统计字符串中每个字符出现的次数
*/
public static void main(String[] args) {
String s = "aaabbbbcccc";
char [] ch = s.toCharArray();
HashMap<Character, Integer> map = new HashMap<Character, Integer>();
for (char c : ch) {
/*if(!map.containsKey(c)){
map.put(c, 1);
}else{
map.put(c, map.get(c)+1);
}
*/
map.put(c, !map.containsKey(c)?1:map.get(c)+1);
}
for (Character key : map.keySet()) {
System.out.println(key+"="+map.get(key) );//b=4 c=4 a=3
}
}
}
(14)
public class Demo1_Map {
/**
集合嵌套 HashMap嵌套hashmap及其遍历
*/
public static void main(String[] args) {
HashMap<Student, String> map1 = new HashMap<Student, String>();
map1.put(new Student("zz", 23), "上海");
map1.put(new Student("ss", 24), "北京");
HashMap<Student, String> map2 = new HashMap<Student, String>();
map2.put(new Student("看看", 23), "上海");
map2.put(new Student("说说", 24), "北京");
HashMap<HashMap<Student, String>, String> map = new HashMap<HashMap<Student,String>, String>();
map.put(map1, "腾讯");
map.put(map2, "华为");
for (HashMap<Student, String> m : map.keySet()) {
String value1 = map.get(m);
for (Student key : m.keySet()) {
String value2 = m.get(key);
System.out.println(key + "_" + value2+"_"+value1);
}
}
/*
Student [name=看看, age=23]_上海_华为
Student [name=说说, age=24]_北京_华为
Student [name=ss, age=24]_北京_腾讯
Student [name=zz, age=23]_上海_腾讯*/
}
}
(15)HashMap与hashTable的区别
1.共同点:
hashMap和hashtable底层都是哈希算法都是双列集合
2.不同点:
(1)hashmap是线程不安全的效率高
hashtable是线程安全的效率低
(2)hashmap可以存储null键和null值
hashtable不可以存储null键和null值
(16)