一.Map
-
严格上说Map并不是集合,而是两个集合之间的映射关系(Map接口没有继承于Collection接口),然而因为
Map可以存储数据(每次存储都应该存储A集合中以一个元素(key),B集合中一个元素(vaule)),我们还是
习惯把Map称之为集合 -
因为:Map接口并没有继承于Collection接口,也没有继承于Iterable接口,所以不能直接对Map使用
for -each操作
二.Map中的方法操作
新建类MapMehodDemo
public class MapMethodDemo {
public static void main(String[] args) {
//创建HashMap
Map<String,Object> map = new HashMap<>();
//将指定的值与此映射中的指定键关联
map.put("key1", "value1");
map.put("key2", "value2");
map.put("key3", "value3");
map.put("key4", "value4");
map.put("key5", "value4");
//打印map
System.out.println(map);
//map的长度
System.out.println(map.size());
//判断是否包含该键
System.out.println(map.containsKey("key1"));
//判断是否包含该值
System.out.println(map.containsValue("value3"));
//根据键获取值
Object o = map.get("key1");
System.out.println(o);
//根据键移除该映射关系
map.remove("key1");
System.out.println(map);
System.out.println("\n----------conllection Values()------------");
//返回此映射中包含的值的 Collection 视图
Collection<Object> collection = new HashSet<>();
collection = map.values();
System.out.println(collection);
System.out.println("---------key keySet()-------------");
//返回该映射中包含的键
Set<String> set = new HashSet<>();
set = map.keySet();
for (String string : set) {
System.out.println(string + "--->" + map.get(string));
}
}
}
三.Set和Map的关系
-
HashSet和HashMap
通过阅读源代码:发现,相同算法的Set底层用的是相同算法的Map. -
把Set的集合对象作为Map的key,再使用一个Object常量作为value
-
因此:跟符合我们说的在Map中,所有的key就是一个Set集合
四.Map的实现类
-
HashMap: 采用哈希表算法,此时Map中的key不会保证添加的先后顺序,key也不允许重复,
- key判断重复的标准是:key1和key2是否equals为true,并且hashCode相等
-
TreeMap: 采用红黑树算法,此时Map中的key会按照自然顺序或定制排序进行排序,也不允许
key重复.key判断重复的标准是:compareTo/compare的返回值是否为0 -
LinkedHashMap:采用链表和哈希表算法,此时Map中的key会保证先后添加的顺序,key不允许重复
key判断重复标准和HashMap中的key判断标准相同 -
Hashtable: 采用哈希表算法,是HashMap的前身(类似于Vector是ArrayList的前身)
所有方法都使用synchronized修饰符,线程都是安全的,但是性能相对HashMap较低 -
Properties: Hashtable的子类,此时要求key和value都是String类型
用来加载资源文件(properties文件)
一般的,我们定义Map,key都使用不可变的类(String),把key作为value的唯一名称
- 性能分析:
HashMap和TreeMap以及LinkedHashMap都是线程不安全的,但是性能较高
解决方案:Map m = Collections.synchronizedMap(Map对象);
Hashtable实现线程安全,但是性能较低
哈希表算法做查询最快
树结构算法:做范围查询最快.–>应用到索引上
不用Hashtable
五.Map案例
新建类MapDemo
//使用Map计算字符串中字符出现次数
public class MapDemo {
public static void main(String[] args) {
String s = "asdwyjxnhkjshaiyiuwehksjdhkfpau";
//获取字符串数组
char[] c = s.toCharArray();
//新建HashMap
//Map<Character,Integer> map = new HashMap<>();//无序
Map<Character,Integer> map = new TreeMap<>();//按照自然排序
//Map<Character,Integer> map = new LinkedHashMap<>();//按照出场顺序排
//遍历字符数组
for (char d : c) {
if (map.containsKey(d)) {
//如果HashMap里包含该key,value+1
Integer i = map.get(d);
map.put(d, i + 1);
}else {
//否则新加进去
map.put(d, 1);
}
}
System.out.println(map);
}
}
七.List,Set,Map的选用
-
List:单一元素集合.
允许元素重复,记录元素的添加顺序 -
Set:单一元素集合
不允许元素重复,不记录元素添加顺序
既要不重复有要记录添加顺序.LInkedHashSet.
- Map:双元素集合,如果存储数据的时候,还得给数据起一个名称,此时考虑使用Map
List,Set以及Map之间转换问题:
List<String> list = new ArrayList<>();
把List转换为Set:
Set<String> set = new HashSet<>(list);//此时会消除重复元素
把Set转换为List:
List<String> list2 = new ArrayList<>(set);
Map与List,Set不能直接转换(Map中的方法可以间接转换)
八.List和Map的综合运用
-
Map在以后运用得非常广泛,表示JavaBean对象,可以做缓存(工具箱)
-
JavaBean对象:多对,属性名=属性值 (属性名表示字段名)
Map对象:每一个key.value就好比一对属性名=属性值
把Map对象转化为JavaBean对象,把JavaBean对象转换为Map对象 -
Set,List,Map三种集合并不是都一直单独使用,偶尔也会综合使用
List<Map<String,Set<Object>>> list = new ArrayList<>();
新建类StudentDemo
//Set,List,Map综合应用
public class StudentDemo {
public static void main(String[] args) {
//一个班
Set<String> set = new HashSet<>();
set.add("小红");
set.add("小蓝");
set.add("小绿");
set.add("小黄");
Set<String> set1 = new HashSet<>();
set1.add("西门吹牛");
set1.add("楚留香");
set1.add("张三丰");
set1.add("叶问");
//一个学院
Map<String,Set<String>> map1 = new HashMap<>();
map1.put("学前班", set);
map1.put("大神班", set1);
Map<String,Set<String>> map2 = new HashMap<>();
map2.put("学前班", set);
map2.put("大神班", set1);
//一个学校
List<Map<String,Set<String>>> list = new ArrayList<>();
list.add(map1);
list.add(map2);
System.out.println(list);
}
}