Map集合是另一个集合体系
* Collection是单值集合
*
* Map集合是一种双值集合,每个元素包含两个值
* Map集合的每个元素的格式:Key=Value(键值对)
* Map集合也被称为"键值对集合"
*
* Map集合的完整格式:{Key1=Value,Key2=Value,Key3=Value,...}
*
* Map集合作用:
* 1,Map集合存储的信息更加具体丰富
* Collection: ["张三","中国","男","3",...]
* Map :[name="张三",国籍="中国",性别"男",年龄"3",...]
* 2,Map集合很适合做购物车这样的系统
* Map :[西瓜=3,茄子=4,..]
* 注意:
* 集合和泛型都只支持引用类型,集合完全可以称为对象容器,存储的都是对象
* Map集合体系
* Map<K,V>(接口,Map集合的祖宗类)
* / \
* TreeMap HashMap<K,V>(实现类,经典的,用的最多)
* \
* LinkedHashMap<K,V>(实现类)
* Map集合的特点:
* 1,Map集合的特点是都是键决定的
* 2,Map集合的键是无序,不重复,无索引
* Map集合后面重复的键对应的元素会覆盖前面整个元素
* 3,Map集合的值无要求
* 4,Map集合的键值对都可以为null
*
* HashMap:元素按照键是无序,不重复,无索引,值不做要求
* LinkedHashMap:元素按键是有序,不重复,无索引,值不做要求
*
* Map集合常见API
* public V put(K key,V value):把指定的键与指定的值添加到Map集合中
* public V remove(Object key):把指定的键,所对应的键值对元素,在Map集合中删除
* public V get(Object key):根据指定的键,在Map中获取对应的值
* public Set<K> KeySet():获取到Map集合中所有的键值对对象的集合(Set集合)
* public boolean containKey(Object Key):判断该集合中是否有此键
*Map集合的遍历方式
* a,”键值对“的方式遍历:先获取Map集合全部的值,再根据键找值
* b,"键值对"的方式遍历,难度较大
* c,jdk1.8之后:Lambda
* a.”键值对“的方式遍历:
* 1,先获取Map集合的全部键的Set集合
* 2,遍历键的Set集合,然后通过键找值
* b."键值对"的方式遍历,
* 1,把Map集合转换成一个Set集合:Set<Map.Entry<K,V>> entrySet()
* 2,此时键值对元素的类型就确定了,类型是键值对实体类型:Map.Entry<K,V>
* 3,接下来foreach遍历这个Set街喊,类型用Map.Entry<K,V>
public class DemoMap {
public static void main(String[] args) {
//无序,不重复,无索引
Map<String, Integer> maps = new HashMap<>();
maps.put("张三", 2);
maps.put("李四", 5);
maps.put("王五", 3);
maps.put("赵六", 8);
maps.put("张三",6);
maps.put(null, null);
System.out.println(maps);//{null=null, 李四=5, 张三=6, 王五=3, 赵六=8}
//2,clear():清空集合
//maps.clear();
//3,isEmpty():判断是否为空
System.out.println(maps.isEmpty());//false
//4,get():根据键值对获取对应值
System.out.println(maps.get("张三"));//6
//5,remove():根据键删除整个元素(删除会返回键的值)
System.out.println(maps.remove(null));//null
//6,containsKey():判断是否包含某个键,包含返回true
System.out.println(maps.containsKey("李四"));//true
//7,containsValue():判断是否包含某个值
System.out.println(maps.containsValue(10));//false
//8,keySet():获取全部键的集合
System.out.println(maps.keySet());//[李四, 张三, 王五, 赵六]
//9,values()获取全部值的集合
System.out.println(maps.values());//[5, 6, 3, 8]
//10,集合的大小
System.out.println(maps.size());//4
//11,合并其他Map集合
HashMap<String, Integer> maps2 = new HashMap<>();
maps2.put("老六", 1);
maps.putAll(maps2);//把Map集合maps2的数据全部倒入到集合maps集合中去
System.out.println(maps);//{李四=5, 张三=6, 老六=1, 王五=3, 赵六=8}
//a,”键值对“的方式遍历:先获取Map集合全部的值,
Set<String> Keys = maps.keySet();
for (String key : Keys) {
//再根据键找值
Integer value = maps.get(key);
System.out.println(key + "=" + value);
}
/**
*b, "键值对"的方式遍历,更加面向对象
* "键值对"想把键值对数据直接当成一个整体遍历,直接使用foreach遍历
* for(被便利集合的元素类型 变量 :集合){
*
* }
* 但Map集合的键值对数据是没有元素类型的,foreach无法直接遍历Map集合
*
* 把Map集合通过代码Set<Map.Entry<String,Integer>> entrySet()转换成Set集合
*
* Set<Map.Entry<String,Integer>> entries = maps.entrySet();
*
* entries = [(李四=5), (张三=6), (老六=1), (王五=3), (赵六=8)]
*
* 此刻键值对元素才能作为一个整体就有了类型,类型就是Map.Entry<String,Integer>实体类型
*/
Set<Map.Entry<String, Integer>> entries = maps.entrySet();
for (Map.Entry<String, Integer> entry : entries) {
String key = entry.getKey();
Integer value = entry.getValue();
System.out.println(key + "=>" + value);
}
//c,Lambda
maps.forEach((k,v) -> System.out.println(k + "=>" + v));
maps.forEach((v,k) -> System.out.println(k + "=>" + v));
}
}
* LinkedHashMap是HashMap的子类
* 添加的元素按照键有序,不重复
* HashSet集合相当于HashMap集合的键都不带值
* LinkedHashMap集合相当于LinkedHashMap集合的键都不带值
*
* 底层原理完全意义,都是基于哈希表按照键存储数据的
* 只是HashMap或者LinkedHashMap的键都多一个附属值
*
* 小结:
* HashMap集合是无序不重复的键值对集合
* LinkedHashMap集合是有序不重复的键值对集合
* 都是基于哈希表存储数据
public class DemoLinkedHashMap {
public static void main(String[] args) {
Map<String, Integer> maps = new HashMap<>();
maps.put("张三", 2);
maps.put("李四", 5);
maps.put("王五", 3);
maps.put("赵六", 8);
maps.put("张三",6);
System.out.println(maps);//{李四=5, 张三=6, 王五=3, 赵六=8}
Map<String, Integer> map = new LinkedHashMap<>();
map.put("张三", 2);
map.put("李四", 5);
map.put("王五", 3);
map.put("赵六", 8);
map.put("张三",6);
System.out.println(map);//{张三=6, 李四=5, 王五=3, 赵六=8}
}
}
TreeMap集合按照键是否排序不重复的键值对集合(默认升序)
* TreeMap集合按照键排序的特点与TreeSet是完全一样的
*
* 小结:TreeMap集合和TreeSet集合都是排序不重复集合
* TreeSet集合的底层是基于TreeMap,只是键没有附属值而已
* 所以TreeMap集合指定大小规则有两种方式
* a,直接为对象的类实现比较器规则接口Comparable,重写比较方法
* b,直接为集合设置比较器Comparator集合重写比较方法
public class DemoTreeMap {
public static void main(String[] args) {
TreeMap<pig, String> pigs = new TreeMap<>();
pigs.put(new pig("佩奇",99.5,500.0), "荷兰");
pigs.put(new pig("乔治",99.4,500.0), "澳大利亚");
pigs.put(new pig("野猪",199.5,500.0), "山上");
System.out.println(pigs);
//{pig{name='乔治', price=99.4, weight=500.0}=澳大利亚, pig{name='佩奇', price=99.5, weight=500.0}=荷兰, pig{name='野猪', price=199.5, weight=500.0}=山上}
TreeMap<pig, String> pig = new TreeMap<>(new Comparator<com.pig>() {
@Override
public int compare(com.pig o1, com.pig o2) {
return Double.compare(o1.getWeight(), o2.getWeight());
}
});
pig.put(new pig("佩奇",99.5,500.0), "荷兰");
pig.put(new pig("乔治",99.4,500.0), "澳大利亚");
pig.put(new pig("野猪",199.5,500.0), "山上");
System.out.println(pigs);
//{pig{name='乔治', price=99.4, weight=500.0}=澳大利亚, pig{name='佩奇', price=99.5, weight=500.0}=荷兰, pig{name='野猪', price=199.5, weight=500.0}=山上}
}
}
class pig implements Comparable{
private String name;
private double price;
private double weight;
public pig() {
}
public pig(String name, double price, double weight) {
this.name = name;
this.price = price;
this.weight = weight;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
@Override
public String toString() {
return "pig{" +
"name='" + name + '\'' +
", price=" + price +
", weight=" + weight +
'}';
}
/*
* 比较者:this
* 被比较者:o
* */
@Override
public int compareTo(Object o) {
//浮点型的大小比较
return Double.compare(this.price,((pig)o).price);
}
}
面试题:读取字符串中每个字符出现的次数
public class Demo {
public static void main(String[] args) {
String datas ="afasdfasqefedfafda3413412341";
HashMap<Character, Integer> hashMap = new HashMap<>();
for (int i = 0; i < datas.length();i++){
char ch = datas.charAt(i);
if (hashMap.containsKey(ch)){
//有这个字符串,其值+1
hashMap.put(ch, hashMap.get(ch)+1);
}else{
//没有这个字符串,说明该字符是第一次统计,直接存入”该字符=1“
hashMap.put(ch, 1);
}
}
System.out.println(hashMap);//{a=5, q=1, 1=3, 2=1, s=2, 3=3, d=3, 4=3, e=2, f=5}
}
}
|