一、双列集合Map
1.1 Map是用来干什么的?
在现实生活中,每个人都有唯一的身份证号,通过身份证号可以查询到这个人的信息,这两者是一对一的关系,在应用程序中,如果想存储这种具有对应关系的数据,则需要使用Java中提供的Map接口。
Map接口是一种双列集合,它的每个元素都包含一个键对象Key和值对象Value,键和值对象之间存在一种对应关系,成为映射。并且键对象Key不能重复,这样在访问Map集合中的元素时,只要指定了Key,就能找到对于的Value。Map又分为HashMap和TreeMap。
1.2 Map的常用方法
添加、删除、修改
Object put(Object key,Object value):将指定key-value添加到(或修改)当前map对象中
void putAll(Map m):将m中的所有key-value对存放到当前map中
Object remove(Object key):移除指定key的key-value对,并返回value
void clear():清空当前map中的所有数据
元素查询
Object get(Object key):获取指定key对应的value
boolean containsKey(Object key):是否包含指定的key
boolean containsValue(Object value):是否包含指定的value
int size():返回map中key-value对的个数
元素视图操作
Set keySet():返回所有key构成的Set集合
Collection values():返回所有value构成的Collection集合
Set entrySet():返回所有key-value对构成的Set集合
1.3 HashMap集合
HashMap集合是Map接口的一个实现类,它用于存储键值映射关系,该集合的键和值允许为空,但键不能重复,且集合中的元素是无序的。HashMap底层是由哈希表结构组成的,其实就是“数组+链表”的组合体,数组是HashMap的主体结构,链表则主要是为了解决哈希值冲突而存在的分支结构。
HashMap的常用方法和Map一样
下面是主要方法的示例练习:
Map map = new HashMap();
//添加
map.put("AA",123);
map.put(45,123);
map.put("BB",56);
//修改
map.put("AA",87);
System.out.println(map);//{AA=87, BB=56, 45=123}
Map map1 = new HashMap();
map1.put("CC",123);
map1.put("DD",123);
map.putAll(map1);
System.out.println(map);//{AA=87, BB=56, CC=123, DD=123, 45=123}
//remove(Object key)
Object value = map.remove("CC");
System.out.println(value);//123
System.out.println(map);//{AA=87, BB=56, DD=123, 45=123}
//clear()
map.clear();//与map = null操作不同
System.out.println(map.size());//0
System.out.println(map);//{}
//--------------------------------
map.put("AA",123);
map.put(45,123);
map.put("BB",56);
// Object get(Object key)
System.out.println(map.get(45));//123
//containsKey(Object key)
System.out.println(map.containsKey("BB"));//true
System.out.println(map.containsValue(123));//true
map.clear();
System.out.println(map.isEmpty());//true
//--------------------------------
map.put("AA",123);
map.put(45,1234);
map.put("BB",56);
//遍历所有的key集:keySet()
Set set = map.keySet();
Iterator iterator = set.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
//AA
//BB
//45
System.out.println();
//遍历所有的value集:values()
Collection values = map.values();
for(Object obj : values){
System.out.println(obj);
}
//123
//56
//1234
System.out.println();
//遍历所有的key-value
//方式一:entrySet()
Set entrySet = map.entrySet();
Iterator iterator1 = entrySet.iterator();
while (iterator1.hasNext()){
Object obj = iterator1.next();
//entrySet集合中的元素都是entry
Map.Entry entry = (Map.Entry) obj;
System.out.println(entry.getKey() + "---->" + entry.getValue());
}
//AA---->123
//BB---->56
//45---->1234
System.out.println();
//方式二:
Set keySet = map.keySet();
Iterator iterator2 = keySet.iterator();
while(iterator2.hasNext()){
Object key = iterator2.next();
Object value1 = map.get(key);
System.out.println(key + "=====" + value1);
}
//AA=====123
//BB=====56
//45=====1234
}
1.4 TreeMap集合
JAVA 中,Map接口还存有一个常用的实现类,TreeMap,它是用来存储键值映射关系的,并且不允许出现重复的键,在TreeMap内部是通过二叉树的原理来保证键的唯一性,这与TreeMap集合存储的原理一样,所以TreeMap中所有的键是按照某种顺序来排列的。
import java.util.Map;
import java.util.TreeMap;
public class TreeMap1{
public static void main(string[]args]){
Map map=new HashMap();
map.put("2","Rose");
map.put("1","Jack");
map.put("3","Lucy");
System.out.println(map);//{1=Jack,2=Rose,3=Lucy}
取出的元素按照键对象的自然顺序进行了排序,这是因添加的元素中键对象是String类型,String类实现了Comparable接口,因此默认会按照自然顺序对元素进行排序。
与TreeSet集合一样,在使用TreeMap集合时,可以通过自定义比较器Comparetor的方式对所有的键进行定制排序,比如可以按照集合中的元素从大到小排序
import java.util.*;
class CustomComparator implements Comparetor{
public int compare(Object obj1,Object obj2){
String key1=(String)obj1;
String key2=(String)obj2;
return key2.compareTo(key1);
}
}
public class TreeMap2{
public static void main(string[]args]){
Map map=new TreeMap(new CustomComparator());
map.put("2","Rose");
map.put("1","Jack");
map.put("3","Lucy");
System.out.println(map);
}
}
先定义CustomComparator针对String类型的键对象K进行比较,在实现compareto()方法时,调用String对象的compareTo()方法,由于方法返回的是 key2.compareTo(key1),因此最终输出结果中的元素按照键值对象从大到小的顺序进行了排序。
二、HashMap和TreeMap比较
(1)HashMap:适用于在Map中插入、删除和定位元素。
(2)Treemap:适用于按自然顺序或自定义顺序遍历键(key)。
(3)HashMap通常比TreeMap快一点(树和哈希表的数据结构使然),建议多使用HashMap,在需要排序的Map时候才用TreeMap.
(4)HashMap 非线程安全 TreeMap 非线程安全
(5)HashMap的结果是没有排序的,而TreeMap输出的结果是排好序的。
在HashMap中通过get()来获取value,通过put()来插入value,ContainsKey()则用来检验对象是否已经存在。可以看出,和ArrayList的操作相比,HashMap除了通过key索引其内容之外,其它方面差异并不大。