黑马程序员——35,泛型应用和Map

本文深入探讨Java中的泛型限定及其在Comparator和Comparable接口中的应用,并详细解析Map接口及其实现类的特点与使用方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

----------- android培训java培训、java学习型技术博客、期待与您交流!------------  

黑马程序员——35,泛型应用和Map

一:泛型限定----》

?  是通配符

<? extends  P>  表示接收的是P类或者P类的子类的对象(上限)

<? super   S > 表示接收的是S类或者S类的父类的对象(下限)

举一个例子说明问题:

         public    static   void    socx(  ArrayList<?  extends Person>   a  )//打印方法
        //可以接收Person类和其子类,这样Person类和其子类的对象都可以用该方打印方法打印元素
         {                 
                         Iterator<?  extends Person>   it=  a.iterator();//取出迭代器
                          while( it.hasNext() )
                          { 
                                    //打印元素名字的操作
                          }
         }

        泛型限定在Comparator和Comparable上的应用:

        如果装有Person类实例的集合以及装有Person类的子类对象的集合都需要元素比较操作时候,定义两个比较器类然后分别建立各自的比较器是非常麻烦的,于是,泛型限定就有作用:

class   Bijiao /*比较器类*/  implements  Comparator<Person> //<? super E>
 //在这里,Comparator既可以接收Person类又可以接收Person类的子类
 //所以,这个比较器类产生的实例比较器既可以用来比较Person类实例,又可以比较Person的子类的实例
{
           public  int  compare(Person  a,Person b)
           {
            //内容…
           }    
}

泛型在Comparable上应用也是类似的:

   class  Student extends  Person   implements  Comparable<Person>//<? super E>
//在这里Comparable既可以接收Person类又可以接收Person类的子类的对象做比较
{
        public   int   compareTo( Person   p)
        {      
           //因为接收过来的有可能是Person类对象,又有可能是Student类对象,所以调用实例P的方法时要注意:只能调用Person类中存在的方法,才能够通过编译。
           //内容…
        }
          //其他内容…
} 
            

二:Map----》

        Map是放在java.util包中的接口,可以理解成双列集合,存放的是键值对(也可以说Map存放的是映射关系)。一个键最多映射一个值,但是一个值可以被多个键映射到。

Map有几个常见的子类:

1,             HashTable---- 底层数据结构是哈希表数据结构,不可以存放null键或者null值,线程同步。

2,             HashMap----底层数据结构是哈希表数据结构,可以存放null键或者null值,线程不同步。

3,             TreeMap----底层数据架构是二叉树结构,可以给键排序,线程不同步。

 

Map的一些常用共有方法(以下都是基于个人理解写的):

void   clear()  //清空集合中的元素

boolean   containsKey(Object  key)   //检测是否含有指定键

boolean   containsValue(Object  value)   //检测是否含有指定值

Set<Map.Entry<K,V>>>  entrySet()   //返回Map中的映射关系

boolean    equals(Object   o)        //指定对象与该Map比较

V   get(Object   key)        //返回指定键的值,如果没有键对应的值就返回null

int   hashCode()            //返回哈希值

boolean    isEmpty()         //判断是否为空

Set<K>   keySet()          //把所有的键存放到一个Set集合中

V  put(K key,   V   value)   //添加键值对,注意:如果Map中有两个相同键的值,新添加的键值对会覆盖原本的键值对,该方法返回的是被剔除的值;如果没有键对应的值就返回null

void   putAll(Map<?  Extends K,? extends V>   m)  //添加指定Map的键值对到该Map中

V   remove(Object   key)  //移除指定键值对,如果没有键对应的值就返回null

int   size()          //返回键值对个数

Collection<V>   values()    //返回一个包含所有值的集合

那么如何获取Map中的键值对呢?

可以利用keySet和entrySet方法:

             //对于一个Map
             Map<String,String>   m= new  HashMap<String,String>();
                  m.put("006","aaa");
                  m.put("002","bbb");
                  m.put("004","ccc");
                  m.put("003","ddd");
                  m.put("005","eee");
                  m.put("001","fff");

          //HashMap底层数据结构是哈希表,还是自动按照哈希表顺序排列
                   Set<String>  s=m.keySet();
                   //把所有键放在Set集合的容器的里面
                   Iterator<String>   it= s.iterator();
                   //有了Set之后就可以建立迭代器
              while(it.hasNext())
              {
                 //it.next()返回String类型的键,利用键获取对应的值
              }

      Map的键值对的第二种取出方式:

     Set<Map.Entry<String,String>>   s=m.entrySet();//取出的是键值对的映射关系
     Iterator<Map.Entry<String,String>>   it=s.iterator();   //获取迭代器
     while(it.hasNext())
{
     Map.Entry<String,String>  me=  It.next();
     String   sKey= me.getKey();//  获取键
     String   sValue=  me.getValue(); // 获取值           
} 

         Map.Entry<String,String>可以看做是一种类型(注意仅仅是看做),Map集合中映射关系类型,这是一种关系类型. 实际上,Map.Entry是Map接口内部的一个public修饰的静态子接口。

        什么时候用HashMap,什么时候用TreeMap要看具体情况

TreeMap的应用例子:

       有一串字符串获取该字符串中每一个字母出现的次数,打印结果是这种形式的:a(6)b(8)...每一个字母都对应着一个数字,这样就形成映射关系了。

import  java.util.*;
class   Mapjs6
{
  public static void  main(String[] args)
  {
     String  a="sss#$dfgggyi++vf--b";
     TreeMap<Character,Integer>    m=method(a);
     method2(m);
  }
  public static TreeMap<Character,Integer> method(String  str)
  {
      char[]  ch=str.toCharArray();//把字符串拆成字符数组
      TreeMap<Character,Integer>    m=new  TreeMap<Character,Integer>();
      for(int x=0;x<ch.length;x++)
      {
         if(!(ch[x]>='a' &&ch[x]<='z'|| ch[x]>='A' && ch[x]<='Z'))
         continue; //如果不是字母字符就结束本次循环,进入下一次循环
 
          Integer  i= m.get(ch[x]);
         if(i==null)
         {
              m.put(ch[x],1);   
         }
         else
        {
         i=i+1;
//如果没有下面m.put(ch[x],i);这句话那么改变的仅仅是i而ch[x]对应的值没有改变!
         m.put(ch[x],i);
         /*
   注意:这句话很重要!不能省略!一定要重新放!
       新的元素会把就的元素剔除。
           */
        }
      }
      soc(m);
      System.out.println();
      return  m;
 
  }
  public  static void method2(TreeMap<Character,Integer> m   )
  {
    Set<Map.Entry<Character,Integer>>   s=m.entrySet();
    Iterator<Map.Entry<Character,Integer>>  it=s.iterator();
      //把映射关系取出来进行操作
       while ( it.hasNext())
         {
           Map.Entry<Character,Integer> a=it.next();
           Character   akey =    a.getKey();
           Integer   avalue = a.getValue();
           soc(akey+"("+avalue+")");
           
         }
  }
 
 
  public static void  soc(Object obj)
  {
   System.out.print(obj);      
   }
}
/*
以上编译运行结果:
{b=1,d=1, f=2, g=3, i=1, s=3, v=1, y=1}
b(1)d(1)f(2)g(3)i(1)s(3)v(1)y(1)
*/

        还有一个就是Map的扩展运用:简单理解就是一个大容器中存放着小容器。(通常是一个Map容器中存放着一个Map容器以及对应的键)视频老师是先写大容器,在写小容器;而本人是先写小容器再写大容器,效果还是一样的。

import java.util.*;
class  Mapjs7
{
   public  static  void  main(String[] args)
   {
     HashMap<String,String>   jichu= new HashMap<String,String>();
     //定义一个基础班容器
     jichu.put("2","sdf");//前面是学生学号后面是姓名
     jichu.put("21","ert");
     jichu.put("13","io");
     jichu.put("19","aheds");
     HashMap<String,String>  tigao=new HashMap<String,String>();
     //定义一个提高班容器
     tigao.put("76","edf");
     tigao.put("43","ycs");
     tigao.put("74","cbhg");
     tigao.put("20","aggs");
    HashMap<String,HashMap<String,String>>   xuexiao=new HashMap<String,HashMap<String,String>>();
       //定义一个学校容器,装的是基础班和提高班
           xuexiao.put("基础班",jichu);
           xuexiao.put("提高班",tigao);
      
        //打印所有学生的学号和名字
 
    Set<Map.Entry<String,HashMap<String,String>>>  s= xuexiao.entrySet();
           //把映射关系放在Set集合中
    Iterator<Map.Entry<String,HashMap<String,String>>>  it=s.iterator();
           //建立迭代器对映射关系进行操作
     while( it.hasNext()   )
     {
      Map.Entry<String,HashMap<String,String>>   m =it.next();  
       String  bjkey  =m.getKey();
       HashMap<String,String>   bjvalue =m.getValue();
       soc("这是"+bjkey+"的学生");
       method(bjvalue);                  
                          
     }
 
                
  }
  public  static void method(HashMap<String,String> jiaoshi )
  {
     Set<Map.Entry<String,String>>     s =jiaoshi.entrySet();
    Iterator<Map.Entry<String,String>>    it= s.iterator();
     while(it.hasNext())
     {
        Map.Entry<String,String>    m=it.next();
         String   s1 =     m.getKey();
         String   s2  =   m.getValue();
        soc(s1+"---"+s2);
    }        
 
 }
  public static  void  soc(Object obj)
  {
     System.out.println(obj);
  }
}
/*
以上代码运行结果是:
这是提高班的学生
74---cbhg
20---aggs
76---edf
43---ycs
这是基础班的学生
2---sdf
13---io
19---aheds
21---ert
 
*/
 
----------- android 培训 java培训 、java学习型技术博客、期待与您交流!------------  

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值