除Collection集合外,JAVA还有另一大体系集合,Map集合,相较于Collection集合,Map集合存储元素方式不同,该集合具有key(键)-value(值)映射关系,存储的元素是成对存在的对象,而key值不允许重复。
Map与Collection相同,都是接口,而相较于Collection没有那么多的分类,Map集合主要包含3个实现类HashMap、Hashtable以及TreeSet,其中HashMap包含一个子类LinkedHashMap,Hashtable本身已经不再常用,而其子类Properties是常用的一个类。
首先看看HashMap,该集合是Map集合的典型实现类,和HashSet相同,都使用了Hash算法,而查看HashSet的源码,不难发现,其实HashMap的底层就是Hashset,所以同样的,该集合判断元素是否存在同样是先比较HashCode,再通过equals()方法进行比较两个元素的内容:
上面就说到,Map集合以键值对的方式存储成对的对象,现在就看看它如何存储:
@Test
public void test1(){
Map map=new HashMap();
map.put("张三",99);
map.put("李四",88);
map.put("王五",100);
map.put("赵六",110);
map.put(new Person("张三",18),88);
map.remove(new Person("张三",18));
Map map2=new HashMap();
map2.put("AA",28);
map2.put("BB",56);
map.putAll(map2);
System.out.println(map);
}
与Collection集合类似,map集合添加元素使用的方法是put(key,value),其中key是不能重复的,而移除元素的remove()方法也是根据key值进行移除。同样与collection的addAll()方法类似,Map集合中也有putAll()方法用于将一个集合中的所有元素添加值至当前集合,运行结果:
除此外,Map集合还拥有一系列其他的方法,比如根据key值获取某个对象的get()方法:
Object value=map.get("张三");
System.out.println(value);
与Collection类似,判断集合中是否包含指定key值的方法containsKey(),或是判断是否包含指定value值的方法containsValue():
System.out.println(map.containsKey("张三"));
System.out.println(map.containsValue(99));
以及获取当前集合的容量size()、判断当前集合是否为空的isEmpty()、判断两个集合是否完全相同的方法equals()等等:
System.out.println(map.size());
System.out.println(map.isEmpty());
System.out.println(map.equals(map2));
值得注意的是equals()方法比较的两个集合是否完全相等,而不是key值全相等或是value值全相等,
新建两个HashMap,并使用上面的方法:
Map map=new HashMap();
map.put("张三",99);
map.put("李四",88);
map.put("王五",100);
map.put("赵六",110);
Map map2=new HashMap();
map2.put("王五",100);
map2.put("赵六",110);
运行结果:
同样的,Map集合也可以使用增强for循环或是迭代器Iterator进行遍历,但由于Map集合本身的特殊性,可以分成三种方式进行遍历。
方法一:获取map中所有的key值,Map中存在一个相应的方法keySet(),返回值为一个Set集合,存储的是该map集合的所有key值:
//1.方式1:获取map中所有的key。keySet()
Map map=new HashMap();
map.put("张三",99);
map.put("李四",88);
map.put("王五",100);
map.put("赵六",110);
Set keys=map.keySet();
for (Object key:
keys) {
Object value=map.get(key);
System.out.println(key+"="+value);
}
运行结果:
方法二:获取map中所有的value,于keySet()方法类似,map中存在相应的方法values(),返回值为一个Collection集合:
//2.方式2:获取map中所有的value。values()
Collection values=map.values();
Iterator iterator=values.iterator();
while (iterator.hasNext()){
Object value=iterator.next();
System.out.println(value);
}
方法三:由于Map集合key-value的形式,map中存在一个内部类Entry,一个Entry指的就是一个key-value对,那么就可以获取map中所有的Entry,同样map中有一个方法entrySet(),返回值为Set,而这里要注意的是,该Set中存的是map中的所有Entry,即key-value对,要想取到其中的key或是value,则还得进行一些操作:
Iterator iterator=set.iterator();
while (iterator.hasNext()){
Entry entry= (Entry) iterator.next();
Object key=entry.getKey();
Object value=entry.getValue();
System.out.println(key+"="+value);
}
在迭代操作时我们需要将每次迭代的元素进行Entry的强转,再通过Entry中的getKey()、getValue()方法分别获取到key和value。
接下来简单的说一下HashMap的子类LinkedHashMap,和LinkedList类似,该集合也是多了一个链表来维护元素间的关系,本质是无序的,但由于链表的存在展现出来有序。
由于Hashtable已经不常用了,这里就不多说了,值得一提的是它的子类Properties,相信进行过jdbc操作的都有用到它,该类主要的作用就是操作Properties文件,此时我们新建一个Properties文件:
username=admin
password=123456
接下来读取该文件中的属性值,首先创建一个Properties对象:
Properties props=new Properties();
其次调用load()方法,传入指定的properties文件:
props.load(new FileInputStream("hello.properties"));
接下来分别获取其中的属性名及其对应的值,这里不对这两个属性进行操作,就直接输出看结果:
String username=props.getProperty("username");
String password=props.getProperty("password");
System.out.println(username+"\n"+password);
值得注意的是由于传入文件时可能会找不到文件,所以需要进行异常处理,运行结果:
最后简单看一看TreeMap,同样与TreeSet类似,该集合是一个根据key值有排序的集合,同样可以通过自然排序(Comparable)以及定制排序(Comparator)进行排序:
这里我们通过定制排序,根据年龄进行排序,若年龄相同则通过名字排序:
Comparator comparator=new Comparator() {
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof Person&&o2 instanceof Person){
Person p1=(Person) o1;
Person p2=(Person) o2;
if (p1.getAge().equals(p2.getAge())){
return p1.getName().compareTo(p2.getName());
}else {
return p1.getAge().compareTo(p2.getAge());
}
}
return 0;
}
};
TreeMap map=new TreeMap(comparator);
map.put(new Person("张三",18),"88");
map.put(new Person("李四",28),"78");
map.put(new Person("王五",38),"68");
map.put(new Person("赵六",48),"58");
map.put(new Person("田七",58),"48");
System.out.println(map);
}
运行结果: