------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------

第一讲 map集合概述

1、将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。
 什么时候使用map集合呢?
 当数据之间存在这映射关系时,就要先想map集合。

2、基本方法
 
 2.1、put(K key, V value)
  
  如果出现添加相同的键时,那么后添加的值会覆盖原有键对应值、并且put方法会返回被覆盖的值。
  特点:保证键的唯一性
重要:
 向map集合中添加元素时,如果返回的是空,说明该键是第一次存入。
 
 2.2、、删除。
  
  clear()
  以前与 key 关联的值;如果没有 key 的映射关系,则返回 null
  并且remove方法会返回被删除的键对应的值。value remove(Object key)
 
 2.3、判断
  
  如何存在,则返回true,否则false
  boolean containsValue(Object value)
  boolean containsKey(Object key)
  boolean isEmpty()
 2.4、获取。
  
  指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null
  get(Object key) 得到键对应的值
  size() 得到集合长度
  entrySet() 返回此映射中包含的映射关系的 Set 视图。
  keySet() 返回此映射中包含的键的 Set 视图。

3、Map子类对象特点
 
  Hashtable:底层是哈希表数据结构,不可以存入null键null值。该集合 是线程同步的,必须实现hashCode和equals方法,jdk1.0,效率低。
  HashMap:底层是哈希表数据结构,允许一个null键和多个null值,该集合是不同步的。将hashtable替代,jdk1.2,效率高。也需要实现元素的hashCode 和equals方法。
  TreeMap:底层是二叉树数据结构。线程不同步。可以用于给map集合中的键进行排序。

4、Map集合的两种取出方式:
 
 4.1、keyset方式
  将map集合中所有的键值取出放到set集合,set集合可以利用迭代器取出每个键值,然后根据map集合的get方法取出每个键对应的值
 4.2、entrySet方式
  将map集合的一种映射关系存入set集合,这种关系就是Map.Entry。然后利用getkey()和getvalue()方法,分别取出键和值

说明:
 Map是一个接口,其实,Entry也是一个接口,它是Map的子接口中的一个内部接口,就相当于是类中有内部类一样。为何要定义在其内部呢?
   原因:a、Map集合中村的是映射关系这样的两个数据,是先有Map这个集合,才可有映射关系的存在,而且此类关系是集合的内部事务。
         b、并且这个映射关系可以直接访问Map集合中的内部成员,所以定义在内部。

import java.util.*;

//Map集合的两种取出方式

class  MapTest
{
 public static void main(String[] args)
 {
  Map <String,String>map=new HashMap<String,String>();//通过泛型定义要存入map集合的是字符串
  map.put("zhnagsan","20");
  map.put("wangwun","26");
  map.put("lisi","24");//向集合中添加元素
  map.put("zhnagqiang","22");
  //keyset方式练习
  Set<String > keyset=map.keySet();//用keyset方法将键存入set集合
  Iterator<String> it=keyset.iterator();//利用迭代器取出键值
  while (it.hasNext())
  {
   String key=it.next();
   String value=map.get(key);//用map的get方法取出键对应的值
   System.out.println(key+":::"+value);
  }

//entryset方式练习
  Set<Map.Entry<String,String>> entryset=map.entrySet();//将map集合的一种映射关系存入set集合
  
  Iterator<Map.Entry<String,String>> newit=entryset.iterator();//利用迭代器取出键值
  while (newit.hasNext())
  {
   Map.Entry<String,String> me=newit.next();
   
   String key=me.getKey();//然后利用getkey()方法,取出键
   String value=me.getValue();//然后利用ggetvalue()方法,取出值
   System.out.println(key+":::"+value);
  }
  
 }
}

练习二  每一个学生都有对应的归属地,归属地用String表示,学生的属性有姓名、年龄,姓名和年龄相同
的学生认为是同一对象。要求保证元素唯一性。
*/

/*
分析:
1.创建学生类,对属性进行描述
2.学生有对应的归属地,有对应关系,存入map集合
3.要保证对象的唯一性,可以用hashmap集合,复写hashcode方法和equals方法

*/

/*
class Student
{
 private String name;
 private int age;
 Student(String name,int age)//创建构造函数
 {
  this.name=name;
  this.age=age;
 
 }
//复写hashcode方法,保证元素唯一性的依据是hashcode方法和equals
 public int hashCode()
 {
  return name.hashCode()+age*78;
 
 }
 public boolean equals(Object obj)
 {
  if(!(obj instanceof Student))
   throw new RuntimeException("类型不符");
  Student s=(Student)obj;
  return this.name.equals(s.name) && this.age==s.age;
 
 }
 public void setName(String name)//设置姓名的方法
 {
  this.name=name;
 
 }
 public String getName()//获取姓名的方法
 {
  return name;
 }
 public void setAge(int age)//设置年纪的方法
 {
 
  this.age=age;
  
 }
 public int getAge()//获取年纪的方法
 {
  return age;
 }
}

class  MapTest
{
 public static void main(String[] args)
 {

HashMap<Student,String>hm=new HashMap<Student,String>();//加入泛型,明确存入的是学生对象
  hm.put(new Student("zhangsan",25),"beijing");
  hm.put(new Student("lisi",22),"nanjing");
  hm.put(new Student("zhaoliu",24),"tianjin");//添加自定义元素
  hm.put(new Student("zhangsan",25),"tianjin");
  
  Set<Student> keyset=hm.keySet();//用keyset方法将键存入set集合
  
  Iterator<Student> it=keyset.iterator();

while (it.hasNext())//利用迭代器取出键值
   {
    Student s=it.next();
    String id=hm.get(s);//用map的get方法取出键对应的值
    System.out.println(s.getName()+s.getAge()+":::"+id);
   }
 }
}
*/

//每一个学生都有对应的归属地,归属地用String表示,学生的属性有姓名、年龄,将学生对象按年龄排序

/*
class Student implements Comparable <Student>
{
 private String name;
 private int age;
 Student(String name,int age)//创建构造函数
 {
  this.name=name;
  this.age=age;
 
 }
 public int compareTo(Student s)//复写compareTo方法
 {
  int num=new Integer(this.getAge()).compareTo(new Integer(s.getAge()));
  if(num==0)
   return this.getName().compareTo(s.getName());
  return num;
 
 }

//复写hashcode方法,保证元素唯一性的依据是hashcode方法和equals
 public int hashCode()
 {
  return name.hashCode()+age*78;
 
 }
 public boolean equals(Object obj)
 {
  if(!(obj instanceof Student))
   throw new RuntimeException("类型不符");
  Student s=(Student)obj;
  return this.name.equals(s.name) && this.age==s.age;
 
 }
 public void setName(String name)//设置姓名的方法
 {
  this.name=name;
 
 }
 public String getName()//获取姓名的方法
 {
  return name;
 }
 public void setAge(int age)//设置年纪的方法
 {
 
  this.age=age;
  
 }
 public int getAge()//获取年纪的方法
 {
  return age;
 }
}
class  MapTest
{
 public static void main(String[] args)
 {

HashMap<Student,String>hm=new HashMap<Student,String>();//加入泛型,明确存入的是学生对象
  hm.put(new Student("zhangsan",25),"beijing");
  hm.put(new Student("lisi",22),"nanjing");
  hm.put(new Student("zhaoliu",24),"tianjin");//添加自定义元素
  hm.put(new Student("zhangsan",25),"tianjin");
  
  Set<Student> keyset=hm.keySet();//用keyset方法将键存入set集合
  
  Iterator<Student> it=keyset.iterator();

while (it.hasNext())//利用迭代器取出键值
   {
    Student s=it.next();
    String id=hm.get(s);//用map的get方法取出键对应的值
    System.out.println(s.getName()+","+s.getAge()+":::"+id);
   }
 }
}
*/

//练习gsauythhjdiiidkoisoo获取字母出现的次数
//希望打印的结果是h(2)i(4).....

/*
分析:
1.将字符数串转换成字符数组,因为要操作每个字符
2.定义一个treemap集合,因为打印结果,不仅有顺序,而且是成对出现
3.遍历字符数组,将每个字母作为键去map集合中去查,如果返回的是null;说明该字符不在map集合中存在
 如果不是null,说明存在,就将字符存入,把次数增加
4.将结果用字符串返回
*/
class  MapTest
{
 public static void main(String[] args)
 {
  String str="gsauythhjdiiidkoisoo";
  String s=getcharCount(str);//调用方法
  System.out.println(s);
 
 }
 public static String getcharCount(String str)
 {
  TreeMap<Character,Integer>ts=new TreeMap<Character,Integer>();//定义treemap集合并甲泛型
  StringBuilder sb=new StringBuilder();

char[]chs=str.toCharArray();//将字符数串转换成字符数组,
  for (int x=0; x<chs.length;x++ )
  {
   Integer value=ts.get(chs[x]);//用map集合的get方法,返回值
   if(value==null)
    ts.put(chs[x],1);
   else
   {
    value=value+1;
    ts.put(chs[x],value);//如果不是null,说明存在,就将字符存入,把次数增加
   }
   
  }
  Set<Character> keyset=ts.keySet();//用keyset方法将键存入set集合
  
  Iterator<Character> it=keyset.iterator();

while (it.hasNext())//利用迭代器取出键值
   {
    Character key=it.next();
    Integer value1=ts.get(key);
    sb.append(key+"("+value1+")");//打印出需要格式
   }
  return sb.toString();
 
 }
}

第二讲  Map扩展知识
 在很多项目中,应用比较多的是一对多的映射关系,这就可以通过嵌套的形式将多个映射定义到一个大的集合中,
 并将大的集合分级处理,形成一个体系。

练习:
/*
map扩展知识。
map集合被使用是因为具备映射关系。
以下是班级对应学生,而学生中学号对应着姓名的映射关系:
"yureban"   Student("01" "zhangsan");
 
"yureban" Student("02" "lisi");
 
"jiuyeban" "01" "wangwu";
"jiuyeban" "02" "zhaoliu";
就如同一个学校有多个教室。每一个教室都有名称。
*/ 
import java.util.*; 
 
class  MapExpandKnow 

    public static void main(String[] args)  
   { 
       //预热班集合 
        HashMap<String,String> yureban=new HashMap<String,String>(); 
        //就业班集合 
        HashMap<String,String> jiuyeban=new HashMap<String,String>(); 
        //学校集合 
  HashMap<String,HashMap<String,String>> czbk=new HashMap<String,HashMap<String,String>>(); 
        //学校中班级集合和名称的映射 
       czbk.put("yureban",yureban); 
       czbk.put("jiuyueban",jiuyeban); 
         
//预热班级中学号与姓名的映射 
       yureban.put("01","zhangsan"); 
        yureban.put("02","lisi"); 
         
        //就业班级中学号与姓名的映射 
       jiuyeban.put("01","wangwu"); 
        jiuyeban.put("02","zhouqi"); 
            
           //直接显示全部学生信息 
       getAllStudentInfo(czbk); 
 
   } 
    //定义一个方法获取全部学生信息,包括在哪个班级,叫什么名字,学号多少 
    public static void getAllStudentInfo(HashMap<String ,HashMap<String,String>> hm) 
    { 
        for (Iterator<String> it=hm.keySet().iterator();it.hasNext() ; )//用keySet取出方式 
       { 
            String s= it.next();//班级名称 
           System.out.println(s+":"); 
           HashMap<String,String> stu=hm.get(s);//班级集合 
 
           getStudentInfo(stu); 
        } 
   } 
     
    //获取班级中学生的信息,包括姓名和学号 
   public static void getStudentInfo(HashMap<String,String> hm) 
   { 
       for (Iterator<String> it=hm.keySet().iterator();it.hasNext() ; ) 
       { 
           String key=it.next();//学号 
           String value=hm.get(key);//姓名 
           System.out.println(key+"..."+value); 
        } 
    } 
}

第三讲 集合框架和数组工具类
 
1、 Collections:它的出现给集合操作提供了更多的功能。这个类不需要创建对象,内部提供的都是静态方法。
 静态方法:
 Collections.sort(list);//list集合进行元素的自然顺序排序。

2、Collections.max(list);//返回list中字典顺序最大的元素。

3、Collections.reverseOrder();//逆向反转排序。

4、Collections.shuffle(list);//随机对list中的元素进行位置的置换。

5、Collections和Collection有什么区别?
重点:
Collections是个java.util下的类,是针对集合类的一个工具类,提供一系列静态方法,
 实现对集合的查找、排序、替换、线程安全化(将非同步的集合转换成同步的)等操作。
 Collection是个java.util下的接口,它是各种集合结构的父接口,继承于它的接口主要有Set和List,提供了关于集合的一些操作,
 如插入、删除、判断一个元素是否其成员、遍历等。

6、Arrays:
 用于操作数组对象的工具类,里面都是静态方法。
 
 将数组转换成集合,有什么好处呢?用aslist方法,将数组变成集合;
 可以通过list集合中的方法来操作数组中的元素:isEmpty()、contains、indexOf、set;
 注意(局限性):数组是固定长度,不可以使用集合对象增加或者删除等,会改变数组长度的功能方法。比如add、remove、clear。
 (会报不支持操作异常UnsupportedOperationException);
 如果数组中存储的引用数据类型,直接作为集合的元素可以直接用集合方法操作。
 如果数组中存储的是基本数据类型,asList会将数组实体作为集合元素存在。

7、 集合变数组:用的是Collection接口中的方法:toArray();
 如果给toArray传递的指定类型的数据长度小于了集合的size,那么toArray方法,会自定再创建一个该类型的数据,长度为集合的size。
 如果传递的指定的类型的数组的长度大于了集合的size,那么toArray方法,就不会创建新数组,直接使用该数组即可,
 并将集合中的元素存储到数组中,其他为存储元素的位置默认值null。
 所以,在传递指定类型数组时,最好的方式就是指定的长度和size相等的数组。

8、增强for循环:

for语句,简化了迭代器。
 格式:增强for循环括号里写两个参数,第一个是声明一个变量,第二个就是需要迭代的容器

9、可变参数(...):
 用到函数的参数上,当要操作的同一个类型元素个数不确定的时候,可是用这个方式,这个参数可以接受任意个数的同一类型的数据。
 和以前接收数组不一样的是:
 以前定义数组类型,需要先创建一个数组对象,再将这个数组对象作为参数传递给函数。现在,直接将数组中的元素作为参数传递即可。
 底层其实是将这些元素进行数组的封装,而这个封装动作,是在底层完成的,被隐藏了。所以简化了用户的书写,少了调用者定义数组的动作。
 如果在参数列表中使用了可变参数,可变参数必须定义在参数列表结尾(也就是必须是最后一个参数,否则编译会失败。)。

10、泛型:jdk1.5版本以后出现的一个安全机制。表现格式:<>
 好处:
 1:将运行时期的问题ClassCastException问题转换成了编译失败,体现在编译时期,程序员就可以解决问题。
 2:避免了强制转换的麻烦。
 只要带有<>的类或者接口,都属于带有类型参数的类或者接口,在使用这些类或者接口时,必须给<>中传递一个具体的引用数据类型。
 泛型技术:其实应用在编译时期,是给编译器使用的技术,到了运行时期,泛型就不存在了。为什么?
 因为泛型的擦除:也就是说,编辑器检查了泛型的类型正确后,在生成的类文件中是没有泛型的。

import java.util.*;
class  CollectionsDemo
{
 public static void main(String[] args)
 {
  sortDemo();

}
 
 //定义一个没有比较器的折半查找方法
 public static int halfSearch(List<String> list,String key)
 {
  //定义变量
  int max,min,mid;
  max = list.size()-1;
  min = 0;
  
  while(min<=max)
  {
   
   mid = (max+min)>>1;
   //得到中间的值
   String str = list.get(mid);
   //调用compareTo方法与关键值比较
   int num = str.compareTo(key);
   
   if(num>0)
    max = mid -1;
   else if(num<0)
    min = mid + 1;
   else
    return mid;
  }
  return -min-1;
 }
 //定义带有比较器的折半方法
 public static int halfSearch(List<String> list,String key,Comparator<String> cmp)
 {
  int max,min,mid;
  max = list.size()-1;
  min = 0;

while(min<=max)
  {
   mid = (max+min)>>1;//  /2;

String str = list.get(mid);
   //调用compare方法与关键值比较
   int num = cmp.compare(str,key);
   if(num>0)
    max = mid -1;
   else if(num<0)
    min = mid + 1;
   else
    return mid;
  }
  return -min-1;
 }

public static void maxDemo()
 {
  List<String> list = new ArrayList<String>();

list.add("abcd");
  list.add("aaa");
  //用集合工具的sort方法进行排序
  Collections.sort(list);
  sop(list);
  //用集合工具的max方法求出最大值
  String max = Collections.max(list/*,new StrLenComparator()*/);
  sop("max="+max);
 }

public static void sortDemo()
 {
  List<String> list = new ArrayList<String>();

list.add("abcd");
  list.add("aaa");
  list.add("zz");
  //用集合工具的sort方法进行排序
  sop(list);

//Collections.sort(list);
  Collections.sort(list,new StrLenComparator());
  //Collections.swap(list,1,2);
  sop(list);
  
 }

public static void sop(Object obj)
 {
  System.out.println(obj);
 }
}

class StrLenComparator implements Comparator<String>
{
 public int compare(String s1,String s2)
 {
  if(s1.length()>s2.length())
   return 1;
  if(s1.length()<s2.length())
   return -1;
  return s1.compareTo(s2);
 }
}

------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------

黑马程序员----------------java基础-----------------Map集合相关推荐

  1. 黑马程序员-----Java基础-----Map

    -----<a href="http://www.itheima.com" target="blank">Java培训.Android培训.iOS培 ...

  2. 黑马程序员 Java基础——List集合

    ------- <a href="http://www.itheima.com" target="blank">android培训</a> ...

  3. 黑马 程序员——Java基础---IO(下)

    黑马程序员--Java基础---IO(下) ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------ 一.概述 Java除了基本的字节流.字符流之外,还提供 ...

  4. 黑马 程序员——Java基础---流程控制

    黑马程序员--Java基础---流程控制 ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------ 一.概述 Java提供了两种基本的流程控制结构:分支结构 ...

  5. 黑马程序员--Java基础加强篇

    开发工具使用 --------------------------------------------------------------------------------------------- ...

  6. 黑马程序员——Java基础--IO流(一)---File类以及其他流对象

    ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 一.File类 File类是将文件系统中的文件和文件夹封装成了对象.提供了更多的属性和行为可以对 ...

  7. 黑马程序员java学习日记——集合框架

    ------- android培训.java培训.期待与您交流! ---------- Java.util包中提供了一些集合类,这些集合类又被称为容器.集合类与数组的不同之处是,数组长度是固定的,集合 ...

  8. 黑马程序员-Java基础:面向对象(上)

    ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 一.面向对象概述 当需求单一,或者简单时,我们一步一步去操作没问题,并且效率也挺高.可随着需求的 ...

  9. 黑马程序员--java基础--其他对象

    ------<a href="http://www.itheima.com" target="blank">Java培训.Android培训.iOS ...

最新文章

  1. java 写文件 错误码_JAVA-读取文件错误1(错误)
  2. python KeyError: 4
  3. python数字类型-Python数字类型介绍
  4. 12.Linux:exec函数族
  5. 如何获得tomcat管理员账号
  6. python相对路径下的shell_shell,python获取当前路径(脚本的当前路径) (aso项目记录)...
  7. ios. GCD 倒计时时间
  8. c语言sleep函数上限多久解除,关于sleep函数的问题,
  9. OpenJudge 2803 碎纸机 / Poj 1416 Shredding Company
  10. GC DevKit 快速入门
  11. SSH 默认端口配置
  12. 【数据库原理实验(openGauss)】金融场景化实验
  13. Dorado 7 Ajax 交互处理
  14. linux文件是否锁定,linux 文件锁定
  15. 成功解决IPython.core.display.HTML object
  16. 车联网也需要“走对路”,用户需求“导航”小度车载OS持续领先
  17. 马士兵 java 学习笔记_马士兵java教程笔记1
  18. 993. 二叉树的堂兄弟节点
  19. 如何安装tushare
  20. 迈德威视相机C#调用例程

热门文章

  1. 2022.3.7-3.13 AI行业周刊(第88期):离职与告别
  2. 5月跳槽会有风险,不跳也会有?
  3. 双目立体视觉(1)- ZED2双目相机介绍
  4. 该进程为关键系统进程,任务管理器无法结束进程
  5. 1-树莓派及配件购买推荐
  6. 韩顺平老师坦克大战优化版
  7. CentOS 5.4 配置本地YUM源
  8. Java压缩png图片文件大小,效果跟Tinypng压缩效果大致一样
  9. slim linux,SLiM (简体中文)
  10. web前端CSS入门知识点总结