Java基础17--Map

来源:互联网 发布:js concat 字符串 编辑:程序博客网 时间:2024/05/16 03:19

17-1,Map集合特点&常用方法

1,Map是一个接口,一次添加一对元素,Collection是一次添加一个元素。Map也成为双列集合,Collection集合称为单列集合。

2,Map<K,V>,是将键映射到值得对象。K-->Key,V-->Value,<K,V>即为键值对。

且一个映射当中不能包含重复的键,每个键最多只能映射到一个值上。也就是说,Map是一个键值对,Map集合中必须保证键的唯一性。

3,Map常用方法。

(1)添加:

value put(key,value):返回前一个与key关联的值,如果没有,则返回null。

比如,先保存了一对<k1,v1>,然后保存<k1,v2>,这时由于k1相同,则v2会覆盖v1,返回v1的值,保证了key的唯一性。

(2)删除:

void clear():清空

value remove(key):根据指定的key删除这个键值对,返回这个key对应的value。

(3)判断:

boolean containsKey(key):判断是否包含指定的key。

boolean containsValue(value):判断是否包含指定的value。

boolean isEmpty():判断是否为空。

(4)获取:

value get(key):通过key取出对应的value,如果不包含这个key,则返回null,可以通过返回null,来判断是否包含指定键。

int size():获取键值对的个数。

 

17-2,常用方法演示

public class Demo{public static void main(String[] args) {Map<Integer,String> map = new HashMap<Integer,String>();method(map);}public static void method(Map<Integer,String> map) {System.out.println(map.put(8,"wangcai"));//nullSystem.out.println(map.put(8,"xiaoqiang"));//wangcaiSystem.out.println(map);//{8-xiaoqiang}//删除System.out.println(map.remove(2));//根据key,删除<k,v>键值对,返回value//判断System.out.println(map.containsKey(8));//获取System.out.println(map.get(8));}}

 

17-3,重点方法keySet()演示图解

1,Set<key> keyset():返回此映射中所包含的键的set视图。

2,演示:

public class Demo {public static void main(String[] args) {Map<Integer,String> map = new HashMap<Integer,String>();method(map);}public static void method(Map<Integer,String> map) {map.put(8,"zhaoliu");map.put(2,"wangwu");map.put(7,"xiaoqiang");map.put(6,"wangcai");/*取出map中的所有元素。原理:通过keySet()方法获取Map中所有的键所在的Set集合,再通过Set的迭代器获取到每一个键,再对每一个键通过get(key)方法获取其对应的值即可。*/Set<Integer> keySet = map.keySet();Iterator<Integer> it = keySet.iterator();while(it.hasNext()) {Integer key = it.next();String value = map.get(key);System.out.println(key + "..." + value);}}}

3,图解:


17-4,重点方法entrySet演示图解

1,public Set<Map.Entry<k,v>>entrySet(),返回此映射锁包含的映射关系的set视图。

2,第二种取出方式entrySet(),

public class Demo {public static void main(String[] args) {Map<Integer,String> map = new HashMap<Integer,String>();method(map);}public static void method(Map<Integer,String> map) {map.put(8,"zhaoliu");map.put(2,"wangwu");map.put(7,"xiaoqiang");map.put(6,"wangcai");/*取出map中的所有元素。原理:通过Map转换成set就可以迭代,这里使用另一种方法:entrySet()。该方法将键和值的映射关系作为对象存储到了set集合中,而这个映射关系的类型就是Map.Entry类型。*/Set<Map.Entry<Integer,String>> entrySet = map.entrySet();Iterator<Map.Entry<Integer,String>> it = entrySet.iterator();while(it.hasNext()) {Map.Entry<Integer,String> me = it.next();Integer key = me.getKey();String value = me.getValue();System.out.println(key + "..." + value);}}}

3,图解:


4,Map.Entry的解释

Map是个接口,Map.Entry是接口中的接口,即,内部接口,表现如下:

interface Map {public static interface Entry {void get();}}class Demo implements Map.Entry {public void get() {...}}

这与内部类差不多是一个原理。

 

17-5,方法values()的演示

1,Collection<V> values()

返回此映射中包含的值得Collection视图。

返回Collection而不是Set的原因是:键是唯一的,而值不是唯一的,所以不能用Set存。

2,演示

public class Demo {public static void main(String[] args) {Map<Integer,String> map = new HashMap<Integer,String>();method(map);}public static void method(Map<Integer,String> map) {map.put(8,"zhaoliu");map.put(2,"wangwu");map.put(7,"xiaoqiang");map.put(6,"wangcai");Collection<String> values = map.values();Iterator<String> it = values.iterator();while(it.hasNext()) {System.out.println(it.next());}}}

 

17-6,Map常用子类对象

1,Map常用子类:

(1)Hashtable:内部结构是哈希表,是同步的,不允许null作为键、值。

(2)HashMap:内部结构是哈希表,不是同步的,允许null作为键、值。

(3)TreeMap:内部结构是二叉树,不是同步的。可以对Map集合中的键进行排序。

HashSet其实是一个HashMap的实例,他的底层代码是根据HashMap实现的。

2,Hashtable

Hashtable下有一个子类是Properties,表示了一个持久的属性集,用来存储键值对型的配置文件的信息,可以和IO技术相结合使用。

 

17-7,HashMap存储自定义对象

1,将Person对象和Person的归属地通过键与值存储到Map集合中。

//先定义Person类public class Person {private String name;private int age;Person(String name,int age) {this.name = name;this.age = age;}public void setName(String name) {this.name = name;}public String getName() {return this.name;}public void setAge(int age) {this.age = age;}public int getAge() {return this.age;}}public class Demo {public static void main(String[] args) {HashMap<Person,String> hm = new HashMap<Student,String>();hm.put(new Person("lisi",38),"北京");hm.put(new Person("zhaoliu",24),"上海");hm.put(new Person("xiaoqiang",31),"沈阳");hm.put(new Person("wangcai",28),"大连");hm.put(new Person("zhaoliu",24),"铁岭");Iterator<Person> it = hm.keySet().iterator();while(it.hasNext()) {Person key = it.next();String value = hm.get(key);System.out.println(key.getName()+":"+key.getAge()+value);}}}

直接这样打印,五个人都会被打印出来,但我们认为键相同则会覆盖,这就必须在Person类中覆写hashCode()和equals()方法,是Student对象具备比较功能,这样就可以不重复取出了。

 

17-8,TreeMap存储自定义对象

与TreeSet一样,TreeMap也具备自定义排序的功能,他是根据Key排序的,Key的对象要实现Comparable接口,并覆写其compareTo方法,下面示例根据Person的age排序的实现。

public class Person {private String name;private int age;Person(String name,int age) {this.name = name;this.age = age;}public void setName(String name) {this.name = name;}public String getName() {return this.name;}public void setAge(int age) {this.age = age;}public int getAge() {return this.age;}public int compareTo(Object o) {Person p = (Person)o;int temp = this.age - p.age;return temp == 0 ? this.name.compareTo(p.name) : temp;}}public class Demo {public static void main(String[] args) {TreeMap<Person,String> tm = new TreeMap<Person,String>();tm.put(new Person("lisi",38),"北京");tm.put(new Person("zhaoliu",24),"上海");tm.put(new Person("xiaoqiang",31),"沈阳");tm.put(new Person("wangcai",28),"大连");tm.put(new Person("zhaoliu",24),"铁岭");Iterator<Map.Entry<Person,String>> it = tm.entrySet().iterator();while(it.hasNext()) {Map.Entry<Person,String> me = it.next();Person key = me.getKey();String value = me.getValue();System.out.println(key.getName()+":"+key.getAge()+value);}}}

Person实现了Comparable接口,其compareTo方法是按照年龄排序的,所以上述程序打印结果是按照年龄排序的。

这个TreeMap也可以通过比较器来排序,只要在创建TreeMap对象时,直接将比较器的实例对象作为实参传给其构造函数即可。

public class ComparatorsByName implements Comparator {public int compare(Object o1,Object o2) {Person p1 = (Person)o1;Person p2 = (Person)o2;int temp = p1.getName().compareTo(p2.getName());return temp == 0 ? p1.getAge() - p2.getAge() : temp;}}

...

构建的时候:

TreeMap<Person,String> tm = newTreeMap<Person,String>(new ComparatorByName());

 

17-9,LinkedHashMap

需求:让HashMap中的元素有序的取出来,即怎么存的就怎么取出。

直接在HashMap的前面加上Linked就可以了。

如:HashMap<Integer,String> hm =new LinkedHashMap<Integer,String>();

加上链表结构就可以有序存入取出了。

 

17-10,Map集合-练习

需求:记录字母出现的次数。

"fdgavcbsacdfs",获取该字符串中每一个字母出现的次数,

要求打印结果格式:a(2)b(1)...

思路:

对于结果的分析发现,字母和数字之间存在着映射关系。而且这种关系很多,很多数据就需要存储起来,能存储映射关系的容器有数组和Map集合。

那么还要思考,数组是基于角标的,角标是有序的编码,在本题中,映射关系的一方是有序的编码么?不是的,所以应该使用Map集合,又发现可以保证唯一性的一方具备这顺序,如a,b,c...,所以可以使用TreeMap集合。

这个集合最终应该存储的是字母和次数的对应关系。

(1)因为操作的是字符串中的字母,所以先将字符串编程字符数组。

(2)遍历字符数组,用每一个字母作为键去查Map集合这个表。如果该字母键不存在,就将该字母作为键,1作为值存入到Map集合中。如果该字母键不存在,就将该字母键对应值取出并+1,再将该字母+1后的值存储到Map集合中。

(3)遍历结束,map集合就记录所有的字母出现的次数。

public class MapTest {public static void main(String[] args) {String str = "fdg+avAdc  bs50da9c-fds";String s = getCharCount(str);System.out.println(s);}public static String getCharCount(String str) {char[] chs = str.toCharArray();Map<Character,Integer> map = new TreeMap<Character,Integer>();for(int i = 0 ; i < chs.length ; i++) {if(!(chs[i]>='a'&&chs[i]<='z'||chs[i]>='A'&&chs[i]<='Z'))continue;Integer value = map.get(chs[i]);int count = 1;if(value != null)count = value + 1;map.put(chs[i],count);}return mapToString(map);}private static String mapToString(Map<Character,Integer> map) {StringBuilder sb = new StringBuilder();Iterator<Charactor> it = map.keySet().iterator();while(it.hasNext()) {Charactor key = it.next();Integer value = map.get(key);sb.append(key+"("+value+")");}return sb.toString();}}

17-11,Map查表法练习

1,Map在有映射关系时可以优先考虑,在查表法中的应用较为多见。

2,若要查一班的张三,一班的李四怎么办?

    map.put("一班","张三");

map.put("一班","李四");

这是不行的,键相同,李四会把张三覆盖。

可以在值得位置上加一个集合,如:map.put("一班",Set<String>);这样一班就对应一个集合了。

3,查表法练习-星期

public class MapTest {public static void main(String[] args) {String week = getWeek(1);System.out.println(week);System.out.println(getWeekByMap(week));}public static String getWeekByMap(String week) {Map<String,String> map = new HashMap<String,String>();map.put("星期一","Mon");map.put("星期二","Tus");map.put("星期三","Wed");map.put("星期四","Thu");map.put("星期五","Fri");map.put("星期六","Sat");map.put("星期日","Sun");map.put("星期天","Sun");return map.get(week);}public static String getWeek(int week) {if(week < 1 || week > 7) {throw new RuntimeException("没有对应的星期");}String[] weeks = {"","星期一","星期二","星期三","星期四","星期五","星期六","星期日"};return weeks[week];}}


0 0
原创粉丝点击