12:集合map、工具类

时间:2021-03-19 09:06:41

一、map集合

Map:一次添加一对元素。Collection 一次添加一个元素。
Map也称为双列集合,Collection集合称为单列集合。
其实map集合中存储的就是键值对(结婚证书), map集合中必须保证键的唯一性。

方法简介:

1、添加 put(K key, V value) 以键值对的形式往里存

putAll(Map<? extends K,? extends V> m) 把一个map里的内容作为值存入进map中。
2、删除 clear() 清空集合

remove(Object key) 清楚其中的一条
3、判断 containsValue(Object value) 判断map中是否包含某个值

containsKey(Object key) 判断map中是否包含某个值

isEmpty()判空
4、获取 get(Object key) 根据key获取值

size() 获取map集合的大小

  • values() 获取map中所有的值,并存放在Collection中
  • entrySet()    Set<Map.Entry<K,V>>返回键值对关系,并存放在Set集合中
  • keySet() 获取map集合中所有的键并存放在Set集合中
a、也可以通过get()方法的返回值来判断一个键是否存在,通过返回null来判断。
b、其中put方法:如果出现添加相同的键,那么后添加的值会覆盖原有键对应的值,并且该方法返回被覆盖的值即原值。
  1. class MapDemo
  2. {
  3. public static void main(String[] args)
  4. {
  5. Map<String,String> map = new HashMap<String,String>();
  6. //添加元素,添加元素,如果出现添加时,相同的键,那么后添加的值会覆盖原有键对应值,并返回以前的值,以前没值就放回null
  7. System.out.println("put:"+map.put("01","zhangsan1"));
  8. System.out.println("put:"+map.put("01","wnagwu"));
  9. map.put("02","zhangsan2");
  10. map.put("03","zhangsan3");
  11. System.out.println("containsKey:"+map.containsKey("022")); 判断
  12. //System.out.println("remove:"+map.remove("02"));删除
  13. System.out.println("get:"+map.get("023"));
  14. map.put("04",null);
  15. System.out.println("get:"+map.get("04"));
  16. //可以通过get方法的返回值来判断一个键是否存在。通过返回null来判断。
  17. //获取map集合中所有的值。
  18. Collection<String> coll = map.values();
  19. System.out.println(coll);
  20. System.out.println(map);
  21. }

两种获取集合元素的方法:
1、keySet()方法获取元素
原理:将Map集合中的所有键存入到Set集合中,因为Set集合具备迭代器,所以可以用迭代方式取出所有的键,再根据get方法获取每一个键对应的值。简单说就是:Map集合---->Set集合 ---->迭代器取出
12:集合map、工具类
  1. class MapDemo2
  2. {
  3. public static void main(String[] args)
  4. {
  5. Map<String,String> map = new HashMap<String,String>();
  6. // Map<Integer,String> map = new HashMap<Integer,String>();
  7. // map.put(8,"zhaoliu");
  8. map.put("02","zhangsan2");
  9. map.put("03","zhangsan3");
  10. map.put("01","zhangsan1");
  11. map.put("04","zhangsan4");
  12. //先获取map集合的所有键的Set集合,keySet();
  13. Set<String> keySet (故意起的,有意义)= map.keySet();
  14. //有了Set集合。就可以获取其迭代器。
  15. Iterator<String> it = keySet.iterator();
  16. while(it.hasNext())
  17. {
  18. String key = it.next();
  19. //有了键可以通过map集合的get方法获取其对应的值。
  20. String value = map.get(key);
  21. System.out.println("key:"+key+",value:"+value);
  22. }
  23. }
  24. }

2、entrySet()方法获取元素:
原理:将Map集合中的映射关系存入到了Set集合中,而这个映射关系的数据类型是Map.Entry(结婚证),在通过迭代器将映射关系存入到Map.Entry集合中,并通过其中的getKey()和getValue()放取出键值。
12:集合map、工具类
  1. class MapDemo2
  2. {
  3. public static void main(String[] args)
  4. {
  5. Map<String,String> map = new HashMap<String,String>();
  6. map.put("02","zhangsan2");
  7. map.put("03","zhangsan3");
  8. map.put("01","zhangsan1");
  9. map.put("04","zhangsan4");
  10. //将Map集合中的映射关系取出。存入到Set集合中。
  11. Set<Map.Entry<String,String>> entrySet = map.entrySet();
  12. Iterator<Map.Entry<String,String>> it = entrySet.iterator();
  13. while(it.hasNext())
  14. {
  15. Map.Entry<String,String> me = it.next();
  16. String key = me.getKey();
  17. String value = me.getValue();
  18. System.out.println(key+":"+value);
  19. }
  20. }
  21. }
补充:关于<Map.Entry<String,String>>
Map是一个接口,其实,Entry也是一个接口,它是Map的子接口中的一个内部接口,就相当于是类中有内部类一样。为何要定义在其内部呢?
原因:
a.Map集合中存的是映射关系这样的两个数据,是先有Map这个集合,才可有映射关系的存在,而且此类关系是集合的内部事务。
b.并且这个映射关系可以直接访问Map集合中的内部成员,所以定义在内部。
  12:集合map、工具类


3、只获取姓名,可以用下面得的,当然可以用上面的:
12:集合map、工具类
12:集合map、工具类


Map常用的子类:
 |--Hashtable :内部结构是哈希表,是同步的。不允许null作为键,null作为值。 //最先出来
  |--Properties:用来存储键值对型的配置文件的信息,可以和IO技术相结合。
 |--HashMap : 内部结构是哈希表,不是同步的。允许null作为键,null作为值。
 |--TreeMap : 内部结构是二叉树,不是同步的。可以对Map集合中的键进行排序。 
:Set底层就是使用了Map集合。
 
 演示1:
  1. public class HashMapDemo {
  2. public static void main(String[] args) {
  3. /*
  4. * 将学生对象和学生的归属地通过键与值存储到map集合中
  5. */
  6. HashMap<Student,String> hm = new HashMap<Student,String>();
  7. hm.put(new Student("lisi",38),"北京");
  8. hm.put(new Student("zhaoliu",24),"上海");
  9. hm.put(new Student("xiaoqiang",31),"沈阳");
  10. hm.put(new Student("wangcai",28),"大连");
  11. hm.put(new Student("zhaoliu",24),"铁岭"); ? o1.getAge-o2.getAge:temp;
  12. }
  13. }
  1. public class TreeMapDemo {
  2. public static void main(String[] args) {
  3. TreeMap<Student,String> tm = new TreeMap<Student,String>(new ComparatorByName());
  4. tm.put(new Student("lisi",38),"北京");
  5. tm.put(new Student("zhaoliu",24),"上海");
  6. tm.put(new Student("xiaoqiang",31),"沈阳");
  7. tm.put(new Student("wangcai",28),"大连");
  8. tm.put(new Student("zhaoliu",24),"铁岭");
  9. Iterator<Map.Entry<Student, String>> it = tm.entrySet().iterator();
  10. while(it.hasNext()){
  11. Map.Entry<Student,String> me = it.next();
  12. Student key = me.getKey();
  13. String value = me.getValue();
  14. System.out.println(key.getName()+":"+key.getAge()+"---"+value);
  15. }
  16. }
  17. }

演示3:LinkedHashMap(有序),和LinkedHashSet使用一样
  1. public class LinkedHashMapDemo {
  2. public static void main(String[] args) {
  3. HashMap<Integer,String> hm = new LinkedHashMap<Integer,String>();
  4. hm.put(7, "zhouqi");
  5. hm.put(3, "zhangsan");
  6. hm.put(1, "qianyi");
  7. hm.put(5, "wangwu");
  8. Iterator<Map.Entry<Integer,String>> it = hm.entrySet().iterator();
  9. while(it.hasNext()){
  10. Map.Entry<Integer,String> me = it.next();
  11. Integer key = me.getKey();
  12. String value = me.getValue();
  13. System.out.println(key+":"+value);
  14. }
  15. }
  16. }


 练习: 1
 * "fdgavcbsacdfs" 获取该字符串中,每一个字母出现的次数。
 * 要求打印结果是:a(2)b(1)...;
 * 思路:
 * 对于结果的分析发现,字母和次数之间存在着映射的关系。而且这种关系很多。
 * 很多就需要存储,能存储映射关系的容器有数组和Map集合。
 * 关系一方式有序编号吗?没有!
 * 那就是使用Map集合。 又发现可以保证唯一性的一方具备着顺序如 a b c ...
 * 所以可以使用TreeMap集合。
 *
 * 这个集合最终应该存储的是字母和次数的对应关系。
 *
 * 1,因为操作的是字符串中的字母,所以先将字符串变成字符数组。
 * 2,遍历字符数组,用每一个字母作为键去查Map集合这个表。
 * 如果该字母键不存在,就将该字母作为键 1作为值存储到map集合中。
 * 如果该字母键存在,就将该字母键对应值取出并+1,在将该字母和+1后的值存储到map集合中,
 * 键相同值会覆盖。这样就记录住了该字母的次数.
 * 3,遍历结束,map集合就记录所有字母的出现的次数。
 
  1. class MapTest1
  2. {
  3. public static void main(String[] args)
  4. {
  5. String s= charCount("ak+abAf1c,dCkaAbc-defa"); //返回一个新的字符串结果
  6. System.out.println(s);
  7. }
  8. public static String charCount(String str)
  9. { //将字符串变成字符数组
  10. char[] chs = str.toCharArray();
  11. //定义map集合表。
  12. Map<Character,Integer> tm = new TreeMap<Character,Integer>();
  13. //因为只存取,不需要TreeMap的特有方法,将他提升为map就可以
  14. for(int x=0; x<chs.length; x++)
  15. {
  16. if(!(chs[x]>='a' && chs[x]<='z' || chs[x]>='A' && chs[x]<='Z'))
  17. continue;
  18. //将数组中的字母作为键去查map表。
  19. Integer value = tm.get(chs[x]); //直接作为键去查表
  20. int count = 1; //计数器
  21. //判断值是否为null.
  22. if(value!=null){
  23. count = value+1; //用个变量记录下
  24. }
  25. // count++;
  26. map.put(chs[i], count);
  27. /* //这种比较麻烦
  28. if(value==null){
  29. map.put(chs[i], 1);
  30. }else{
  31. map.put(chs[i], value+1); //直接往集合中存储字符和数字,为什么可以,因为自动装箱
  32. }
  33. */
  34. }
  35. }
  36. //System.out.println(tm);
  37. // 上边已经解决,转换它的那种结果a(2)b(1).
  38. return mapToString(map);
  39. }
  40. private static String mapToString(Map<Character, Integer> map) {
  41. StringBuilder sb = new StringBuilder();
  42. Iterator<Character> it = map.keySet().iterator();
  43. while(it.hasNext()){
  44. Character key = it.next();
  45. Integer value = map.get(key);
  46. sb.append(key+"("+value+")");
  47. }
  48. return sb.toString();
  49. }
  50. }

练习2:
map什么时候用, Map在有映射关系时,可以优先考虑。在查表法中的应用较为多见。
  1. public class MapTest2 {
  2. public static void main(String[] args) {
  3. String week = getWeek(1); //查表
  4. System.out.println(week);
  5. System.out.println(getWeekByMap(week));
  6. }
  7. public static String getWeekByMap(String week){
  8. Map<String,String> map = new HashMap<String,String>();
  9. map.put("星期一","Mon");
  10. map.put("星期二","Tus");
  11. map.put("星期三","Wes");
  12. map.put("星期日","Sun");
  13. map.put("星期天","Sun");
  14. return map.get(week);
  15. }
  16. public static String getWeek(int week){
  17. if(week<1 || week>7)
  18. throw new RuntimeException("没有对应的星期,请您重新输入");
  19. String[] weeks = {"","星期一","星期二"};
  20. return weeks[week];
  21. }
  22. }

第二:Collections工具类

Collections和Collection有什么区别?

  • Collection是集合框架中的一个顶层接口,它里面定义了单列集合的共性方法。它有两个常用的子接口
List:对元素都有定义索引。有序的。可以重复元素。
Set:不可以重复元素。无序。

  • Collections ? o1.compareTo(o2) : temp;
  • }
  • }

源码:  Collections.sort(list,new ComparatorByLength())的排序原理
12:集合map、工具类
  1. public static <T> void mySort(List<T> list,Comparator<? super T> comp){
  2. for (int i = 0; i < list.size()-1; i++) {
  3. for (int j = i+1; j < list.size(); j++) {
  4. if(comp.compare(list.get(i), list.get(j))>0){
  5. // T temp = list.get(i);
  6. // list.set(i, list.get(j));
  7. // list.set(j, temp);
  8. Collections.swap(list, i, j);
  9. }
  10. }
  11. }

源码: Collections.sort(list)的排序原理
  1.  public static <T extends Comparable<? super T>> void mySort(List<T> list){ 长度比较
  2. //<T extends Comparable<? super T>>需要限定,继承; i < list.size()-1; i++) {
  3.    for (int j = i+1; j < list.size(); j++) {
  4.     if(list.get(i).compareTo(list.get(j))>0){
  5.   
  6.      Collections.swap(list, i, j);
  7.  public static void demo_2(){二分查找、最值
  8.   List<String> list = new ArrayList<String>();
  9.   list.add("abcde");
  10.   list.add("cba");
  11.   list.add("aa");
  12.   list.add("zzz");
  13.   list.add("cba");
  14.   list.add("nbaa");
  15. // Collections.sort(list); 没顺序不能折半,先排序
  16.   System.out.println(list);