前言:
当前姐妹们对“java比较map”大概比较关心,朋友们都想要了解一些“java比较map”的相关资讯。那么小编同时在网上收集了一些有关“java比较map””的相关资讯,希望我们能喜欢,同学们快快来了解一下吧!8.6 Map
引入:
根据之前学习的集合我们知道,一个集合中可以存放学生信息,那现在有这么一个问题需要我们解决,根据一个学生的学号找到一个学生的信息并打印输出。拿我们前边学习的List与Set集合来说我们要如何完成?我们可以遍历学生对象,然后根据条件匹配,拿到学生信息。很显然这可以完成工作,但有点麻烦。
针对这种情况,Java给我们提供了Map集合。
Map用于保存具有映射关系的数据,是以一种键值对的形式进行存放的。因此Map集合里保存着两组值,一组用于保存Map里的key,另外一组用于保存Map里的value,key和value都可以是任何引用类型的数据。而Map的key不允许重复,即同一个Map对象的任何两个key通过equals方法比较总是返回false。
Key和value是一一对应的关系,即通过指定的key,总能找到唯一的value对象。Map里的key放在一起可以看成一个Set集合,实际上Map中包含了一个keySet()方法,用于返回Map里所有key组成的Set集合。
Map中的所有value放在一起可以看成一个list集合,元素与元素之间可以重复,每个元素可以根据索引来查找。只是Map中的索引不再使用整数值,而是以另外一个对象作为索引。如果需要从Map中取出元素,则需要提供该元素的key索引。
Map接口中定义了如下常用方法:
Ø void clear():删除Map对象中所有的key-value对。
Ø Boolean containsKey(Object key):查询Map中是否包含指定的key,如果有则返回true。
Ø Boolean containsValue(Object value):查询Map中是否包含一个或多个Value,如果有返回true。
Ø Set entrySet():返回Map中包含的key-value对所组成的set集合,每个集合元素都是Map.Entry(Entry是Map的内部类)对象。
Ø Object get(Object key):返回指定key所对应的value,如果此Map中不包含该key,返回null。
Ø boolean isEmpty():查询Map是否为空,如果为空返回true。
Ø Set keySet():返回该Map中所有的key组成的Set集合。
Ø Object put(Object key,Object value):添加一个key-value对,如果当前Map中已有一个与该key相当的key-value对,则新的key-value对会覆盖原来的key-value对。这里这个值的返回,如果当前key值上没有东西,返回null。如果有东西再在当前key值上放东西,返回之前放在这个key地方的值。
Ø void putAll(Map m):将Map的实例对象m中的key-value对复制到本Map中。
Ø Object remove(Object key):删除指定key-value对,返回被删除key所关联的value,如果该key不存在,返回null。
Ø int size():返回该Map里key-value对的个数。
Ø Collection values():返回该Map中所有value组成的Collection。
Map中包含一个内部类Entry,该类封装了一个key-value对。Entry包含了如下三个方法:
Ø Object getKey():返回Entry里包含的key值。
Ø Object getValue():返回Entry里包含的value值。
Ø Object setValue(V value):设置该Entry里包含的value值,并返回新的value值。
举例1:
public static void main(String[] args) throws Exception{
Map<String,String> map = new HashMap<String,String>();
//首先往map中存放数据
map.put("one","zhangsan");
map.put("two", "lisi");
map.put("three","wangwu");
//取得map中key-value的数量
System.out.println(map.size());//3
//判断map中是否存在value为lisi的对象
System.out.println(map.containsValue("lisi"));//true
//判断map中是否存在key为one的对象
System.out.println(map.containsKey("one"));//true
//判断当前map对象是否是空对象,即不含任何元素对象
System.out.println(map.isEmpty());//false
//创建一个新的Map对象m2将m2中的key-value复制到map中去
Map<String,String> m2 = new HashMap<String,String>();
m2.put("four","zhaoliu");
m2.put("five", "qianqi");
map.putAll(m2);
//重新获取map的key-value的个数
System.out.println(map.size());//5
//删除指定key的key-value对
String one = map.remove("one");
System.out.println(one);//zhangsan
System.out.println(map.size());//4
//遍历map
//方式1,获取所有的键,根据键来拿值
Set<String> set = map.keySet();
for(String key:set){
String value = map.get(key);
System.out.println(key+”---”+value);
}
//方式2,获取键值对对象,遍历
Set<Map.Entry<String,String>> set = map.entrySet();
for(Map.Entry<String, String> entry : set){
System.out.println(entry.getKey()+"===="+entry.getValue());
}
//常用的方式3,根据key值进行遍历
Iterator<String> it = map.keySet().iterator();
while (it.hasNext()) {
String str = it.next();
System.out.println(str + "-" + map.get(str));
}
}
8.6.1 HashMap和Hashtable实现类
HashMap和Hashtable都是Map的典型实现类,两者之间的关系完全类似于ArrayList和Vector。除此之外两者之间的典型区别:
1、 Hashtable是一个线程安全的Map实现,但HashMap是线程不安全。所以HashMap比Hashtable性能更高一点。
2、 Hashtable不允许使用null作为key和value,而HashMap则可以。
举例1:
public static void main(String[] args) throws Exception{
Map map = newHashMap();
map.put(null, null);
System.out.println(map.size());
Map m2 = newHashtable();
m2.put(null, null);
System.out.println(m2.size());
}
HashMap正常执行,而Hashtable则报空指针异常错误。
注意:尽量不要使用可变对象作为HashMap的key,如果使用了可变对象作为了map的key,则在程序中尽量不要去修改变量。
举例2:
public static void main(String[] args) throws Exception{
String str = "abc";
Map map = new HashMap();
map.put(str, "zhangsan");
str = "123";
System.out.println(map.get(str)); //输出null
System.out.println(map.get("abc")); //输出zhangsan
}
这里添加一个key—value的存值问题。
(1) key:String—value:String
(2) key:Integer—value:String
(3) key:String—value:Student
(4) key:Student—value:String
第四种,当出现了两个参数一样的对象进行添加时,这个时候我只想添加一个进去,如何解决?
在相应的对象中重写相应的方法。
举例3:关于map集合的嵌套问题,比如说:
浪曦有高薪就业班,全日制班。而每个班里都有学生。那我想用集合存放浪曦所有的学生,我应该怎么定义集合。
public static void main(String[] args){
HashMap<String, HashMap<String, Student>> langsin = new HashMap<String, HashMap<String, Student>>();
HashMap<String, Student> E24 = new HashMap<String, Student>();
Student Est = new Student("张三", 24);
Student Est1 = new Student("张三1", 24);
E24.put("002", Est);
E24.put("012", Est1);
langsin.put("E24", E24);
HashMap<String, Student> F06 = new HashMap<String, Student>();
Student Fst = new Student("李四", 23);
Student Fst1 = new Student("李四1", 23);
F06.put("003", Fst);
F06.put("007", Fst1);
langsin.put("F06", F06);
Set<String> langsinSet = langsin.keySet();
for (String str : langsinSet) {
System.out.println(str);
HashMap<String, Student> Value = langsin.get(str);
Set<String> Set = Value.keySet();
for (String str1 : Set) {
Student stu = Value.get(str1);
System.out.println("\t" + str1 + "----" + stu);
}
}}
举例4:在HashMap中嵌套ArrayList集合。
public static void main(String[] args){
HashMap<String,ArrayList<Student>> hm = new HashMap<String,ArrayList<Student>>();
ArrayList<Student> al1 = new ArrayList<Student>();
Student l1st = new Student();
al1.add(l1st);
hm.put(“001”,al1);
ArrayList<String> al2 = new ArrayLIst<String>();
Sudnet l2st = new Student();
al2.add(l2st);
hm.put(“004”,al2);
Set<String> set = hm.keySet();
for(String str:set){
System.out.println(str);
ArrayList<Student> al = hm.get(str);
for(Student st:al){
System.out.println(st);
}
}
}
举例5:
ArrayList集合嵌套HashMap集合。
ArrayList<HashMap<String,String>> arr = new ArrayList<HashMap<String,String>>();
//数据添加
for (HashMap<String, String> hm : arr) {
Set<String> set = hm.keySet();
for (String key : set) {
String value = hm.get(key);
System.out.println(key + "---" + value);
}
}
举例6:
Map里一个Map里有一个Map。
Set<String> MapSet = czbkMap.keySet();
for (String MapKey : MapSet) {
System.out.println(MapKey);
HashMap<String, ArrayList<Student>> MapValue = langsinMap
.get(MapKey);
Set<String> MapValueSet = MapValue.keySet();
for (String MapValueKey : MapValueSet) {
System.out.println("\t" + MapValueKey);
ArrayList<Student> MapValueValue St= MapValue
.get(MapValueKey);
for (Student s : MapValueValue) {
System.out.println("\t\t" + s.getName() + "---"
+ s.getAge());
}
}
}
8.6.2 LinkedHashMap实现类
LinkedHashMap是HashMap的子类,同LinkedHashSet一样,LinkedHashMap在存储数据元素时同样使用了链表来维护key-value对的存放顺序,该链表负责维护Map的迭代顺序,迭代顺序与key-value对的插入顺序保持一致。
举例1:
publicstaticvoid main(String[] args) throws Exception{
Map<String,String> map = new HashMap<String,String>();
map.put("1", "zhangsan1");
map.put("2", "zhangsan2");
map.put("3", "zhangsan3");
map.put("10", "zhangsan1");
map.put("20", "zhangsan20");
map.put("30", "zhangsan30");
for(Map.Entry<String,String> entry : map.entrySet()){
System.out.println(entry.getKey()+"====="+entry.getValue());
}
}
输出结果:
3=====zhangsan3
20=====zhangsan20
2=====zhangsan2
10=====zhangsan1
1=====zhangsan1
30=====zhangsan30
举例2:
替换上例程序的中第一行代码
LinkedHashMap<String,String> map = new LinkedHashMap<String,String>();
输出结果:
1=====zhangsan1
2=====zhangsan2
3=====zhangsan3
10=====zhangsan1
20=====zhangsan20
30=====zhangsan30
8.6.3 Properties属性类
Properties类是Hashtable类的子类,该对象在处理属性文件时非常方便。Properties类可以把Map对象和属性文件关联起来,从而可以把Map对象中的key-value对写入到属性文件中,也可以把属性文件中的“属性名=属性值”加载到Map对象中。由于属性文件里的属性名、属性值只能是字符串类型,所有Properties里的key、value都是字符串类型。
该类的常用方法如下:
Ø String getProperty(String key):获取Properties中指定属性名对应的属性值。
Ø String getProperty(String key,String defaultValue):方法重载,获取Properties中指定属性名对应的属性值,如果此属性名不存在时,返回默认的defaultValue值。
Ø Object setProperty(String key,String value):设置属性值,类似于Map的put()方法。
Ø void load(InputStream inStream):从属性文件中加载key-value对。
Ø void store(OutputStream out,String comments):将Properties中的key-value对输入到指定的属性文件中。
属性文件格式:在windows系统下属性文件常以.ini进行结尾,在Java中属性文件以.properties结尾。
举例1:
public static void main(String[] args) throws Exception{
Properties prop = new Properties();
prop.setProperty("name","zhangsan");
prop.put("age","24");
prop.store(new FileOutputStream("./test.ini"), "注释内容");
Properties prop2 = new Properties();
//FileInputStream文件输入流,使用prop的load()方法进行加载文件
prop2.load(new FileInputStream("./test.ini"));
prop2.setProperty("gender", "male");
System.out.println(prop2.get("age"));
System.out.println(prop2.getProperty("name"));
//FileOutputStream文件输出流,使用prop的store()方法将porp对象的信息保存到指定的文件中
prop2.store(new FileOutputStream("./test.properties"), "属性文件");
}
程序输出结果:
bankCode = 62202 1602 0131 34567
bankPass = 123456
userName = zhangsan
userAge = 24
8.6.4 SortedMap接口与TreeMap实现类
如同Set接口派生出SortedSet子接口,SortedSet接口有一个实现类TreeSet一样,Map接口也有一个SortedMap接口,SortedMap接口也有一个实现类TreeMap。TreeMap就是一个红黑树数据结构,每个key-value对即作为红黑树的一个节点。TreeMap存储key-value对时,需要根据key对节点进行排序。TreeMap保证所有的key-value对都处于有序的状态。
TreeMap的两种排序方式:
1、 自然排序:TreeMap的所有key必须实现Comparable接口,而且所有的key应该是同一个类的对象,否则抛出ClassCastException(类型转换异常)。
2、 定制排序:创建TreeMap对象时,传入一个Comparator对象,该对象负责对TreeMap中的所有key进行排序。采用定制排序时不需要key实现Comparable接口。
TreeMap提供的常用方法如下:
Ø Map.Entry firstEntry():返回该Map中最小key所对应的key-value对,如果Map为空,则返回null。
Ø Object firstKey():返回该Map中最小key值,如果该Map为空,则返回null。
Ø Map.Entry lastEntry():返回Map中最大key所对应的key-value对,如果Map为空,则返回null。
Ø Object lastKey():返回该Map中最大key值,如果该Map为空,则返回null。
Ø Map.Entry higherEntry(Object key):返回该Map中位于key后一位的key-value对。如果后面不存在则返回为null。
Ø Object higherKey(Object key):返回该Map中位于key后一位的key值,如果后面不存在则返回为null。
Ø Map.Entry lowerEntry(Object key):返回该Map中位于key前一位的key-value对。如果前面不存在则返回为null。
Ø Object lowerKey(Object key):返回该Map中位于key前一位的key值。如果前面不存在则返回为null。
Ø SortedMap subMap(Object fromKey,Object toKey):返回该Map的子Map,其key的范围是从fromKey(包括)到toKey(不包括)。
Ø SortedMap tailMap(Object fromKey):返回该Map的子Map,其key的范围是大于fromkey(包括)的所有key。
Ø SortedMap headMap(Object toKey):返回该Map的子Map,其key的范围是小于toKey(不包括)的所有key。
举例1:
package com.langsin.test;
import java.util.Comparator;
import java.util.TreeMap;
class MyTest implements Comparable<Object>{
int count;
public MyTest(int count){
this.count = count;
}
public int compareTo(Object obj) {
MyTest te = (MyTest)obj;
return count>te.count?1:(count<te.count?-1:0);
}
}
publicclass TestTreeMap {
public static void main(String[] args) {
Comparator<MyTest> comp = new Comparator<MyTest>(){
public int compare(MyTest m1, MyTest m2) {
if(m1.count>m2.count){
return -1;
}
if(m1.count<m2.count){
return 1;
}
return 0;
}
};
//首先实现treeMap的定制排序
TreeMap<MyTest,String> map = new TreeMap<MyTest,String>();
map.put(new MyTest(-3), "123");
map.put(new MyTest(1), "456");
map.put(new MyTest(3), "789");
System.out.println(map);
System.out.println(map.firstEntry());
}
}
8.6.5 WeakHashMap实现类
WeakHashMap与HashMap的用法基本相似,区别在于HashMap的key保留了对实际对象的强引用。即:只要HashMap不被销毁,该HashMap的所有key所引用的对象就不会被垃圾回收,HashMap也不会自动删除这些key所对应key-value对。WeakHashMap的key只保留了对实际对象的弱引用,即:WeakHashMap的对象的key所引用的对象没有被其他强引用变量所引用,则这些key所引用的对象可能被垃圾回收,WeakHashMap也可能自动删除这些key所对应的key-value对。
对于WeakHashMap,大家仅作了解,知道与HashMap的区别即可。
举例1:
publicstaticvoid main(String[] args) throws Exception{
WeakHashMap map = newWeakHashMap();
map.put(new String("123"), "123");
String str = newString("456");
map.put(str, "456");
map.put("456", "abc");
System.out.println(map); //输出内容
System.gc();
System.out.println(map);
}
8.6.7 EnumMap实现类
EnumMap是一个与枚举类一起使用的Map实现,EnumMap中所有的key都必须是单个枚举类的枚举值。创建EnumMap时必须显示或隐式指定它对应的枚举类。
EnumMap根据key的自然顺序,即在枚举类中的定义顺序来维护key-value对的顺序。调用Map的方法keySet()、entrySet()、values()遍历EnumMap时可以看到这种顺序。
EnumMap不允许使用null作为key,但允许使用null作为value。
创建EnumMap时必须指定一个枚举类,从而与使EnumMap和指定枚举类关联起来。
举例1:
publicstaticvoid main(String[] args) throws Exception{
Map map = new EnumMap(Planet.class);
map.put(Planet.EARTH, "地球");
map.put(Planet.MARS, "火星");
//map.put(Planet.PLUTO, "冥王星");
map.put(Planet.VENUS, "金星");
map.put(Planet.SATURN, "土星");
map.put(Planet.JUPITER, "木星");
map.put(Planet.MERCURY, "水星");
map.put(Planet.NEPTUNE, "海王星");
map.put(Planet.URANUS, "天王星");
System.out.println(map);
}
标签: #java比较map