此博客仅用于本人自学总结,仅供参考,如发现错误,请不要喷我,我是初学者.
Map集合不是Collection接口的子类也不是他的父类,而是独立与Collection接口的接口.
Map接口Map<K,V>是一个映射集合,即K与V相对应.
K为Key值,V为Value值
Key值是无序的,不可重复的,放在Set集合之中.(当Key值为一个类时,需重写equals和hashcode方法,以HashMap为例)
Value值无序的可以重复的,放在Collection中.
实际是是把这两个值放在Entry,然后装进Map集合之中.
Entry(Map接口中的一个嵌套接口)是无序的,不可重复的,放在Set集合中.
所以说可以理解为数据在集合中的保存方法是成对保存的!
Map接口的特性简述
HashMap实现类:Map的主要实现类,优点是效率高,缺点是线程不安全,不能用在多线程中(可以存储null,健壮性好)
LinkedHashMap实现Map接口,继承HashMap接口:使用了链表,所以LinkedHashMap在遍历时是可以按照put顺序
遍历的,而且由于添加了指针的缘故,遍历的效率提升了.
TreeMap实现类:(底层是红黑树)和TreeSet一样,TreeMap可以自动对集合进行排序(为基本数据类型时),也可以自定义排序 方法(比较器),这里需要注意的是,TreeMap排序取决于Key值.
Hashtable实现类:Hashtable是类似于Vector集合在List集合中的地位差不多,都是比较老的不怎么用到的集合,特性也和 Vetor差不多,即效率较低,但线程安全(不能存放null的key值和value值)
Properties继承Hashtable实现Map:Properties 的key和value值只能是String类型
HashMap
HashMap具有不重复,无序的特性
public static void main(String[] args) {
HashMap<Integer, Integer> map1 = new HashMap<>();
map1.put(1,5);
map1.put(1,1);
map1.put(2,9);
map1.put(5,9);
map1.put(3,9);
System.out.println(map1);
}
上诉代码输出结果为1=1,2=9,3=9,5=9.
为何如此,首先Map集合中的K值时不可重复而V值是可重复的,体现在K值为1的元素只有一个,当K值相同时,后来put的entry对象会把前面的entry对象(里面有K和V),覆盖,所以上述代码输出结果为1=1而不是1=5.
Map集合是无序的,但是集合会自动按K值自然排序.
遍历
很可惜的是Map集合及不可以用下标操作集合,也不可以用迭代器,故Map集合的遍历需寻求其他途径
Map集合中的Key以Set集合存储,Value以Collection集合储存,Key和Value合起来以Entry的方式存储在Set集合之中
故对以上各个值的遍历可以遵循相应的集合特性
对Key值的遍历
public static void main(String[] args) {
Map map = new HashMap<>();
map.put("AS",1.9f);
map.put("aa",1.9f);
map.put(7,1.9f);
map.put("bb",1.9f);
map.put(3,2.9f);
/*keySet返回一个存储了Key值的Set集合*/
Set set = map.keySet();
//1.使用for each遍历
for (Object key:set){
System.out.println(key);
}
//2.使用迭代器遍历
Iterator iterator = set.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
Map中的KeySet方法会返回Key的Set集合,然后就可以用迭代器对key遍历(加强for底层也是迭代器)
对Value值的遍历
对Value遍历的思路也差不多,不过value是存放在Collection集合中的,得到Map.value()的返回值(一个Collection集合)
然后通过增强for循环和迭代器遍历(Collection接口没有get(index)的方法)
对Entry的遍历
public static void main(String[] args) {
Map map = new HashMap<>();
map.put("AS",1.9f);
map.put("aa",1.9f);
map.put(7,1.9f);
map.put("bb",1.9f);
map.put(3,2.9f);
/*map.entrySet()返回一个entry的Set集合*/
Set<Map.Entry> entrySet = map.entrySet();
//迭代器遍历
Iterator<Map.Entry> iterator = entrySet.iterator();
while (iterator.hasNext()){
//方法一
System.out.println(iterator.next());
//方法二
Map.Entry entry = iterator.next();
System.out.println(entry.getKey()+"="+entry.getValue());
}
//for each遍历
for (Map.Entry entry:entrySet){
System.out.println(entry);
}
}
Entry中有得到key和value值的方法.即getKey和getValue
此处应注意的是,如果Key值是一个自定义类,则需要添加比较器才可以遍历,内部或者外部比较器皆可.
TreeMap
TreeMap集合之于HashMap就和TreeSet和HashSet集合一样,TreeMap一开始就对集合按Key值进行了排序,如果Key是自定义的类,可以通过new 比较器的匿名内部类的方法设定排序方法,List集合是通过Collections.sort方法中new 比较器内部类排序,Set集合可以转变成List集合然后用Coections排序(详见我的博客 http://120.55.53.172:7001/moon/CommTopic/toOneTopic?id=196Set集合使用匿名内部类)
@Test public void test(){ TreeMap<Object, Object> treeMap = new TreeMap<>(new Comparator<Object>() { @Override public int compare(Object o1, Object o2) { return 0; } });
直接在TreeMap对象中new 匿名内部类.
但需注意的是,上面的这种方法只能按Key值排序,如果你想要按照Value值排序则比较麻烦,需要通过entrySet()得到entry的一个Set集合,然后把这个Set集合转化成List集合,然后使用Collections加上匿名内部类比较器的方法对集合进行排序.
public void test3(){ TreeMap<String,Double> map = new TreeMap<>(); map.put("qq",11.2); map.put("bb",11.0); map.put("cc",155.2); map.put("dd",19.0); Set<Map.Entry<String,Double>> set = map.entrySet(); List<Map.Entry<String,Double>> list = new ArrayList(set); Collections.sort(list, new Comparator<Map.Entry<String, Double>>() { @Override public int compare(Map.Entry<String, Double> o1, Map.Entry<String, Double> o2) { return -(o1.getValue()>o2.getValue()?1:o1.getValue()==o2.getValue()?0:-1); } }); System.out.println(list); }
注意集合类型转换过程中的泛型需要写完整!!