day18_Map集合+泛型

来源:互联网 发布:数据挖掘领域大牛 编辑:程序博客网 时间:2024/05/16 20:30

01-常用对象API(集合框架-泛型-概述)


泛型:

    jdk1.5出现的安全机制。

   

好处:

    1,将运行时期的问题ClassCastException转到了编译时期。

    2,避免了强制转换的麻烦。

   

<>:什么时候用?当操作的引用数据类型不确定的时候。就使用<>。将要操作的引用数据类型传入即可.

  其实<>就是一个用于接收具体引用数据类型的参数范围。

  

在程序中,只要用到了带有<>的类或者接口,就要明确传入的具体引用数据类型 。

 

02-常用对象API(集合框架-泛型-擦除&补偿)

 

泛型技术是给编译器使用的技术,用于编译时期。确保了类型的安全。

 

运行时,会将泛型去掉,生成的class文件中是不带泛型的,这个称为泛型的擦除。

为什么擦除呢?因为为了兼容运行的类加载器。

 

泛型的补偿:在运行时,通过获取元素的类型进行转换动作。不用使用者在强制转换了。

 

03-常用对象API(集合框架-泛型-在集合中的应用)

示例代码:GenericDemo2.java演示treeset,泛型里面全都是引用数据类型,而且也只能是引用数据类型

 

04-常用对象API(集合框架-泛型-泛型类)

 

我们在搞完了基本原理过后,还有其他的用处,它还能为我们提供设计上的便捷

/*

public class Tool {

 

    private Object object;

 

    public Object getObject() {

        return object;

    }

 

    public void setObject(Object object) {

        this.object = object;

    }

   

}

*/

//在jdk1.5后,使用泛型来接收类中要操作的引用数据类型。

//泛型类。什么时候用?当类中的操作的引用数据类型不确定的时候,就使用泛型来表示。

public class Tool<QQ>{

    private QQ q;

 

    public QQ getObject() {

        returnq;

    }

 

    public void setObject(QQ object) {

        this.q = object;

    }

 

 

使用

Tool<Student> tool = new Tool<Student>();

       

//      tool.setObject(newWorker());

//      Student stu =tool.getObject();

//      Tool tool = new Tool();     

//      tool.setObject(newWorker());      

//      Student stu = (Student)tool.getObject();

 

 

05-常用对象API(集合框架-泛型-泛型方法)

 

/**

     * 将泛型定义在方法上。

     * @param str

     */

    public <W> void show(W str){

        System.out.println("show : "+str.toString());

    }

    public void print(QQ str){

        System.out.println("print : "+str);

    }

   

    /**

     * 当方法静态时,不能访问类上定义的泛型。如果静态方法使用泛型,

     * 只能将泛型定义在方法上。

     * @param obj

     */

    public static <Y> void method(Y obj){

        System.out.println("method:"+obj);

    }

 

使用

    Tool<String> tool = new Tool<String>();

       

        tool.show(new Integer(4));

        tool.show("abc");

        tool.print("hahah");

//      tool.print(newInteger(8));

        Tool.method("haha");

        Tool.method(new Integer(9));

 

06-常用对象API(集合框架-泛型-泛型接口)

//泛型接口,将泛型定义在接口上。

interface Inter<T>{

    public void show(T t);

}

 

 

class InterImpl2<Q> implements Inter<Q>{

    public void show(Q q){

        System.out.println("show :"+q);

    }

}

 

 

 

 

class InterImpl implements Inter<String>{

    public void show(String str){

        System.out.println("show :"+str);

    }

 

使用
    InterImpl in = new InterImpl();

        in.show("abc");

       

        InterImpl2<Integer>in2 = newInterImpl2<Integer>();

        in2.show(5);

 

07-常用对象API(集合框架-泛型-泛型限定(上限))

现在我们的泛型类,泛型接口,泛型方法都已经说完了,现在来说一些高级应用

public static void main(String[] args) {

 

        ArrayList<String>al = new ArrayList<String>();

       

        al.add("abc");

        al.add("hehe");

       

        ArrayList<Integer>al2 = newArrayList<Integer>();

       

        al2.add(5);

        al2.add(67);

       

        printCollection(al);

        printCollection(al2);

    }

 

    /**

     * 迭代并打印集合中元素。

     * @param al

     */

    public static voidprintCollection(Collection<?> al) { 

   

        Iterator<?> it =al.iterator();

       

        while(it.hasNext()){

//          T str = it.next();

//          System.out.println(str);

            System.out.println(it.next().toString());

        }

       

    }

 

泛型的通配符:? 未知类型。


当我们的工具类中如果返回有这样的t的话也,这个T是不是可以进行操作,是,对于我们的?号来讲,仅在不明确类型,不对这个类型进行操作时用来表示,一般我们用?号的情况比较多一些

时间:0----13分钟

下面讲解另外一个知识点


ArrayList<Person> al= new ArrayList<Person>();

       

        al.add(new Person("abc",30));

        al.add(new Person("abc4",34));

       

        ArrayList<Student>al2 = newArrayList<Student>();

       

        al2.add(new Student("stu1",11));

        al2.add(new Student("stu2",22));

        ArrayList<String>al3 = new ArrayList<String>();

       

        al3.add("stu3331");

        al3.add("stu33332");

       

        printCollection(al2);

        printCollection(al);


08-常用对象API(集合框架-泛型-泛型限定(下限))

接着上面的代码,从方法前面的代码都一样的

/**

     * 迭代并打印集合中元素。

     *

     * 可以对类型进行限定:

     * ? extends E:接收E类型或者E的子类型对象。上限!

     *

     * ? super E :接收E类型或者E的父类型。下限!

     * @param al

     */

public static voidprintCollection(Collection<?super Student> al){

        Iterator<? super Student> it = al.iterator();

       

        while(it.hasNext()){

           

            System.out.println(it.next());

        }

    }

 

接下来我们说说什么时候用

09-常用对象API(集合框架-泛型-泛型限定(上限的体现))

public static void main(String[] args) {

 

        ArrayList<Person>al1 = new ArrayList<Person>();

       

        al1.add(new Person("abc",30));

        al1.add(new Person("abc4",34));

       

        ArrayList<Student>al2 = new ArrayList<Student>();

       

        al2.add(new Student("stu1",11));

        al2.add(new Student("stu2",22));

       

       

        ArrayList<Worker>al3 = new ArrayList<Worker>();

       

        al3.add(new Worker("stu1",11));

        al3.add(new Worker("stu2",22));

       

        ArrayList<String>al4 = new ArrayList<String>();

        al4.add("abcdeef");

//      al1.addAll(al4);//错误,类型不匹配。

       

        al1.addAll(al2);

        al1.addAll(al3);

       

        System.out.println(al1.size());

       

       

//      printCollection(al2);

//      printCollection(al);

    }

}

 

/*

 * 一般在存储元素的时候都是用上限,因为这样取出都是按照上限类型来运算的。不会出现类型安全隐患。

 *

 */

 

class MyCollection<E>{

    public void add(E e){

   

    }

    public void addAll(MyCollection<? extends E> e){

       

    }

 

10-常用对象API(集合框架-泛型-泛型限定(下限的体现))

public static void main(String[] args) {

 

        TreeSet<Person>al1 = new TreeSet<Person>(new CompByName());

       

        al1.add(new Person("abc4",34));

        al1.add(new Person("abc1",30));

        al1.add(new Person("abc2",38));

       

        TreeSet<Student>al2 = new TreeSet<Student>(new CompByName());

       

        al2.add(new Student("stu1",11));

        al2.add(new Student("stu7",20));

        al2.add(new Student("stu2",22));

       

       

        TreeSet<Worker>al3 = new TreeSet<Worker>();

       

        al3.add(new Worker("stu1",11));

        al3.add(new Worker("stu2",22));

       

        TreeSet<String>al4 = new TreeSet<String>();

        al4.add("abcdeef");

//      al1.addAll(al4);//错误,类型不匹配。

       

//      al1.addAll(al2);

//      al1.addAll(al3);

       

//      System.out.println(al1.size());

       

       

       

        Iterator<Student>it = al2.iterator();

        while(it.hasNext()){

            System.out.println(it.next());

        }

       

    }

}

 

 

/*

 * class TreeSet<Worker>

 * {

 *     Tree(Comparator<? super Worker> comp);

 * }

 *

 * 什么时候用下限呢?通常对集合中的元素进行取出操作时,可以是用下限。

 *

 */

 

class CompByName implements Comparator<Person>{

 

    @Override

    public int compare(Person o1, Person o2) {

       

        int temp = o1.getName().compareTo(o2.getName());

       

        return temp==0? o1.getAge()-o2.getAge():temp;

    }

   

}

 

class CompByStuName implements Comparator<Student>{

 

    @Override

    public int compare(Student o1, Student o2) {

       

        int temp = o1.getName().compareTo(o2.getName());

       

        return temp==0? o1.getAge()-o2.getAge():temp;

    }

   

}

 

class CompByWorkerName implements Comparator<Worker>{

 

    @Override

    public int compare(Worker o1, Worker o2) {

       

        int temp = o1.getName().compareTo(o2.getName());

       

        return temp==0? o1.getAge()-o2.getAge():temp;

    }

 

11-常用对象API(集合框架-泛型-泛型限定(通配符的体现))

 

12-常用对象API(集合框架-集合查阅的技巧)

===========================================================

 

集合的一些技巧:

 

需要唯一吗?

需要:Set

    需要制定顺序:

            需要: TreeSet

            不需要:HashSet

            但是想要一个和存储一致的顺序(有序):LinkedHashSet

不需要:List

    需要频繁增删吗?

        需要:LinkedList

        不需要:ArrayList

       

如何记录每一个容器的结构和所属体系呢?

 

看名字!

 

 

List

    |--ArrayList

    |--LinkedList

 

Set

    |--HashSet

    |--TreeSet

 

后缀名就是该集合所属的体系。

 

前缀名就是该集合的数据结构。

 

看到array:就要想到数组,就要想到查询快,有角标.  

看到link:就要想到链表,就要想到增删快,就要想要 add get remove+frist last的方法

看到hash:就要想到哈希表,就要想到唯一性,就要想到元素需要覆盖hashcode方法和equals方法。

看到tree:就要想到二叉树,就要想要排序,就要想到两个接口Comparable,Comparator 。

 

而且通常这些常用的集合容器都是不同步的。

 

 

============================================

 

01-常用对象API(集合框架-Map集合特点&常用方法)

Map:一次添加一对元素。Collection 一次添加一个元素。

    Map也称为双列集合,Collection集合称为单列集合。

    其实map集合中存储的就是键值对。

    map集合中必须保证键的唯一性。

   

   

常用方法:

1,添加。

    valueput(key,value):返回前一个和key关联的值,如果没有返回null.

 

2,删除。

    void  clear():清空map集合。

    valueremove(key):根据指定的key翻出这个键值对。

 

3,判断。

    booleancontainsKey(key):

    booleancontainsValue(value):

    booleanisEmpty();

 

4,获取。

    valueget(key):通过键获取值,如果没有该键返回null。

                    当然可以通过返回null,来判断是否包含指定键。

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

 

02-常用对象API(集合框架-常用方法演示)

 

public static voidmethod(Map<Integer,String>map){//学号和姓名

       

       

        // 添加元素。

        System.out.println(map.put(8,"wangcai"));//null

        System.out.println(map.put(8,"xiaoqiang"));//wangcai存相同键,值会覆盖。

        map.put(2,"zhangsan");

        map.put(7,"zhaoliu");

       

       

        //删除。

//      System.out.println("remove:"+map.remove(2));

       

        //判断。

//      System.out.println("containskey:"+map.containsKey(7));

       

        //获取。

        System.out.println("get:"+map.get(6));

        System.out.println(map);

    }

 

03-常用对象API(集合框架-重点方法keySet演示图解)

//取出map中的所有元素。

        //原理,通过keySet方法获取map中所有的键所在的Set集合,在通过Set的迭代器获取到每一个键,

        //在对每一个键通过map集合的get方法获取其对应的值即可。

        /*

        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);

           

        }

        */

原理图:


04-常用对象API(集合框架-重点方法entrySet演示图解).

/*

         * 通过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);

           

        }


05-常用对象API(集合框架-方法values演示).

map.put(8,"zhaoliu");

        map.put(2,"zhaoliu");

        map.put(7,"xiaoqiang");

        map.put(6,"wangcai");

       

       

        Collection<String>values = map.values();

       

        Iterator<String>it2 = values.iterator();

        while(it2.hasNext()){

            System.out.println(it2.next());

        }

 

 

06-常用对象API(集合框架-Map集合-常见子类对象)

Map常用的子类:

    |--Hashtable :内部结构是哈希表,是同步的。不允许null作为键,null作为值。

        |--Properties:用来存储键值对型的配置文件的信息,可以和IO技术相结合。       

    |--HashMap: 内部结构是哈希表,不是同步的。允许null作为键,null作为值。

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

 

07-常用对象API(集合框架-Map集合-HashMap存储自定义对象)

/*

         * 将学生对象和学生的归属地通过键与值存储到map集合中。

         *

         */

       

        HashMap<Student,String>hm = new HashMap<Student,String>();

 

       

        hm.put(new Student("lisi",38),"北京");

        hm.put(new Student("zhaoliu",24),"上海");

        hm.put(new Student("xiaoqiang",31),"沈阳");

        hm.put(new Student("wangcai",28),"大连");

        hm.put(new Student("zhaoliu",24),"铁岭");

       

//      Set<Student> keySet= hm.keySet();    

//      Iterator<Student> it= keySet.iterator();

       

        Iterator<Student>it = hm.keySet().iterator();

       

        while(it.hasNext()){

            Student key = it.next();

            String value = hm.get(key);

            System.out.println(key.getName()+":"+key.getAge()+"---"+value);

        }

       

08-常用对象API(集合框架-Map集合-TreeMap存储自定义对象)

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

       

        tm.put(new Student("lisi",38),"北京");

        tm.put(new Student("zhaoliu",24),"上海");

        tm.put(new Student("xiaoqiang",31),"沈阳");

        tm.put(new Student("wangcai",28),"大连");

        tm.put(new Student("zhaoliu",24),"铁岭");

       

       

        Iterator<Map.Entry<Student,String>> it = tm.entrySet().iterator();

       

        while(it.hasNext()){

            Map.Entry<Student,String> me = it.next();

            Student key = me.getKey();

            String value = me.getValue();

           

            System.out.println(key.getName()+":"+key.getAge()+"---"+value);

        }

 

 

day18 学习结果:

 

1,泛型类,泛型方法,泛型接口什么时候用?并举例!

 

2,泛型的通配符,以及泛型的限定的表现形式,和用法,以及什么时候用?

    ? extends E: 存储元素对象的时候用,你定义的是E类型,我们可以存储E类型或者E的子类型的对象。

    ? super E:从容器中取出元素时使用,容器中有E类型对象,取出时可使用E类型接收,或者E的父类型接收。比如比较器。

 

3,泛型的细节作为了解?

 

4,要求api中涉及泛型限定的方法一定要看的懂并会用,比如TreeSet集合的构造函数。

 

5,Map集合的特点以及常见子类的特点?

 

6,Map集合中,取出所有元素原理,以及keySet,entrySet方法的使用,必须会?

 

7,Map集合和Collection集合的区别?

    1,

    Map中一次存储是键值对。

    Collection中一次存储是单个元素。

    2,

    Map的存储使用的put方法。

    Collection存储使用的是add方法。

    3,

    Map的取出,是讲Map转成Set,在使用迭代器取出。

    Collection取出,使用就是迭代器。

    4,

    如果对象很多,必须使用容器存储。

    如果元素存在着映射关系,可以优先考虑使用Map存储或者用数组,

    如果没有映射关系,可以使用Collection存储。

   

 

8,Map集合的使用场景。要求,将常见的体现之一:查表法回顾一下,并用map集合完成一次查表法。

 

 

练习:

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

要求打印结果是:a(2)b(1)...;

 


0 0
原创粉丝点击