您的位置:首页 > 职场人生

黑马程序员_java集合框架2

2013-11-20 16:39 323 查看
---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------

一、      Map集合

5.1、Map集合的特点

Map集合:该集合存储键值对,一对一对往里存,而且要保证键的唯一性。 

常用方法:

1、增加

put(K key, V value)

putAll(Map<? extends K,? extends V> m)

2、删除

clear()

remove(Object key)

3、判断

containsKey(Object key)

containsValue(Object value)

isEmpty()

4、获取

size()

values()

get(Object key)

Map中两种特殊的获取方式:

(Map集合的取出原理:将Map集合转换成Set集合,通过迭代器取出);

Set<key>  entrySet():将Map中所有的键存入到Set集合,因为Set具有迭代器,所以可以用迭代方式取出所有的键,再根据get方法获取每一个键所对应的值。

Set<Map.Entry<K,V>>
 entrySet() :将Map集合中的映射关系存入到了Set集合中,而这个关系的数据类型就是Map.Entry。

示例:

import java.util.*;
 

class MapDemo   

{  

    public static void main(String[] args)   

    {  

        /*Map<String,String> map = new HashMap<String,String>(); 

        //添加元素时,如果出现了添加相同的键,那么后添加的键值将会覆盖之原有的键值; 

        //并返回之前的键值; 

        System.out.println(map.put("001","Java01"));//打印结果为null; 

        System.out.println(map.put("001","Java05"));//打印结果为Java01; 

        map.put("002","Java02"); 

        map.put("003","Java03"); 

        map.put("004","Java04"); 

 

        System.out.println(map.size());//获取Map集合的长度; 

        System.out.println(map.containsKey("002"));//判断集合中是否包含键002; 

        System.out.println(map.get("002"));//获取键002的值; 

        //可以通过get方法的返回值来判断一个键是否存在,通过返回null来判断; 

        System.out.println(map.remove("002"));//删除002键,并返回002的值; 

 

        Collection<String> coll = map.values();//获取Map集合中所有的值; 

        System.out.println(coll); 

        System.out.println(map);*/  

  

        Map<String,String> map = new HashMap<String,String>();  

        map.put("001","Java01");  

        map.put("002","Java02");  

        map.put("003","Java03");  

        map.put("004","Java04");  

  

        //keyEntry方法获取:  

        //将Map集合中的映射关系取出存入到Set集合中;  

        Set<Map.Entry<String,String>> es = map.entrySet();  

        Iterator<Map.Entry<String,String>> it = es.iterator();  

        while(it.hasNext())  

        {  

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

            String key = me.getKey();  

            String value = me.getValue();  

            System.out.println("key:"+key+"***value:"+value);  

        }  

        /* //keySet方法获取: 

        Set<String> ks = map.keySet();//获取Map集合中所有键的Set集合; 

        Iterator<String> it = ks.iterator();//有了Set集合就可以使用迭代器了; 

        while(it.hasNext()) 

        { 

            String key = it.next(); 

            String value = map.get(key); 

            System.out.println("key:"+key+"***value:"+value); 

        }*/ 

 

     5.2、Map集合中三个常用类

              |---HashTable

              特点:底层是哈希表数据结构,不可以存入null键null值;该集合是线程同步的。  
JDK1.0出现,效率低。

              |---HashMap

              特点:底层是哈希表数据结构,允许使用null键null值;该集合是不同步的。  
JDK1.2出现,效率高。

              |---TreeMap

              特点:底层是二叉树数据结构;该集合线程不同步。可以给Map集合中的键进行排序。

               Map和Set很像,Set的底层就是用了Map集合。

       5.3、Map集合扩展

二、      集合框架的工具类

Collections,Arrays中的各种方法参考API
1.6文档。

       6.1、Arrays方法中asList方法可以将数组转换成List集合。其好处是:可以使用集合的思想和方法来操作数组。

       但要注意:将数组变成集合后不可以使用List的增删方法,因为数组的长度是固定的。如果出现增删情况,将会发生UnSupportedOperationException异常。

       如果数组中的元素都是对象,当变成集合时,数组中的元素就直接转换成集合中的元素;如果数组中的元素都是基本数据类型,那么会将该数组作为集合中的元素存在。

       6.2、集合变数组:使用Collections集合中的toArray方法。

       注意:当指定类型的数组长度小于集合的长度(size),该方法内部会重新创建一个新的数组,长度为集合的size;当指定类型的数组长度大于集合的长度(size),就不会新创建数组,而是使用传递进来的数组,所以创建一个刚刚好的数组最优。

       集合变数组的好处:为了限定对数组的操作(增删)。

       6.3、增强for循环

       格式:

       for(数据类型 变量名:被遍历的集合(Collection)或者数组)

       {

       }

示例:

import java.util.*;  

  

class ForEachDemo   

{  

    public static void main(String[] args)   

    {  

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

        al.add(5);  

        al.add(3);  

        al.add(12);  

        al.add(9);  

        al.add(7);  

  

        for(Integer in:al)  

        {  

            System.out.println(in);  

        }  

  

        /*Iterator<Integer> it = al.iterator(); 

        while(it.hasNext()) 

        { 

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

        }*/  

    }  

}

       forEach对集合进行遍历:只能获取集合中的元素,但不能对集合进行操作;

       迭代器除了遍历,还可以对集合中的元素进行删除操作;

       如果是ListIterator,在对集合遍历时还可以进行增删改查等操作。

       传统for循环与增强for循环的区别:增强for循环有一个局限性,必须有被遍历的目标。

       建议在遍历数组时使用传统for循环,因为传统for循环可以定义角标。

 

       6.4、可变参数

       只要将操作的元素作为参数传递即可。隐式的将这些参数封装成了数组。

       在使用可变参数时注意:可变参数一定要定义在参数列表最后面。

import java.util.*;  

  

class ParameterDemo  

{  

    public static void main(String[] args)   

    {  

        show("java",5,4,8,3,9,2);//此时的可变参数列表要放到最后面;  

    }  

  

    public static void show(String str,int... arr)  

    {  

        System.out.println(Arrays.toString(arr));  

    }  



 

6.5、静态导入

当类名重名时,需要指定具体的报名;

当方法名重名时,需要指定其所属的对象或者类。     

import java.util.*;  

import static java.util.Arrays.*;  

                //导入的是Arrays这个类中所有的静态成员;  

  

class StaticImportDemo   

{  

    public static void main(String[] args)   

    {  

        int[] arr = {3,8,12,1,5,23,36};  

  

        sort(arr);//省略Arrays;  

        int index = binarySearch(arr,5);  

        System.out.println(index);  

        System.out.println(Arrays.toString(arr));  

        //此处的Arrays不能够省略,因为toString与Object类中的toString重名,  

        //此时要指定是调用哪一个的toString;  

    }  

}

四、      泛型

4.1、泛型概述

泛型:JDK1.5版本后出现的新特性,用于解决安全问题,是一种类型安全机制。

优点:1)、将运行时期出现的问题ClassCastException转移到了编译时期,方便与程序员解决问题,让运行时期问题减少,提高了安全性;

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

       泛型格式:通过<>来定义要操作的引用数据类型。

 

       4.2、泛型的使用方法

       通常在集合框架中很常见,在API文档中,只要见到<>就要定义泛型。

       其实<>就是用来接收类型的。在使用集合时,将集合要存储的数据类型作为参数传递到<>即可。

 

       4.3、泛型类的用法

       当类中要操作的引用数据类型不确定时,早期定义Object来完成,现在定义泛型来完成。

       示例:

class Student  

{  

}  

  

class Worker  

{  

}  

  

class Tools<QQ>//将Tools定义成泛型类;  

{  

    private QQ q;  

    public void setObject(QQ q)  

    {  

        this.q = q;  

    }  

    public QQ getObject()  

    {  

        return q;  

    }  

}  

  

  

class GenericDemo1   

{  

    public static void main(String[] args)   

    {  

        Tools<Worker> t = new Tools<Worker>();  

        t.setObject(new Worker()); //此处再只接受Worker类型的对象;  

        Worker w = t.getObject();//此时再也不用强转型了;  

    } 

       4.4、泛型方法

       泛型类定义的泛型方法在整个类中有效,如果被方法使用,泛型类的对象明确要操作的具体类型以后,所有要操作的类型都固定了。

       为了让不同方法操作不同类型,而且类型还不确定,就可以将泛型定义在方法上。

       特殊:静态方法不可以访问类上定义的泛型,如果静态方法操作的应用数据类型不确定,可以将泛型定义在静态方法上。

       示例:

/*class Demo<T> 



    public void show(T t) 

    { 

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

    } 

    public void print(T t) 

    { 

        System.out.println("Pring :"+t); 

    } 

     

}*/  

  

class Demo  //此处使用class Demo<T>也行,可以将方法show中的<T>去掉;  

{           //此时show方法上的类型将与Demo上的一致,而print方法不受影响;  

    public <T> void show(T t)//将泛型使用在方法上;  

    {                        //将避免所有方法都固定接受一个类型;  

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

    }  

    public <Q> void print(Q q)  

    {  

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

    }  

    public static <W> void method(W w)//此处的静态方法将不能够访问类上定义的泛型;  

    {                                 //可以将泛型定义在方法 上;  

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

    }  

}  

class GenericDemo2   

{  

    public static void main(String[] args)   

    {  

        //泛型方法:  

        Demo d = new Demo();  //此时的编译运行将都能够通过;  

        d.show("Hello java");  

        d.show(3);  

        d.print("Hello world");  

        d.print(4);  

          

        //以下方法是定义泛型类  

        /* 

        Demo<String> d  = new Demo<String>();//此时指定的操作类型为String类型; 

        d.show(1);  //此处传入的是int类型的就将会导致编译失败; 

        d.print("Hello world");//传入String类型,符合要求; 

        */  

    }  



4.5、泛型限定

       ?  :通配符,也可以理解为占位符。

       泛型的限定:

       ? extends E :可以接受E类型或者E的子类型,即上限。

       ? super E :可以接受E类型或者E的父类型,即下限。

       示例:

import java.util.*;  

  

class GenericDemo3   

{  

    public static void main(String[] args)   

    {  

        TreeSet<Student> ts = new TreeSet<Student>(new comp());  

        ts.add(new Student("java01"));  

        ts.add(new Student("java05"));  

        ts.add(new Student("java02"));  

        ts.add(new Student("java04"));  

        ts.add(new Student("java03"));  

          

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

        while(it.hasNext())  

        {  

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

        }  

  

        TreeSet<Worker> ts1 = new TreeSet<Worker>(new comp());  

        ts1.add(new Worker("java---01"));  

        ts1.add(new Worker("java---05"));  

        ts1.add(new Worker("java---02"));  

        ts1.add(new Worker("java---04"));  

        ts1.add(new Worker("java---03"));  

  

        Iterator<Worker> it1 = ts1.iterator();      

        while(it1.hasNext())  

        {  

            System.out.println(it1.next().getName());  

        }  

    }  

}  

  

class comp implements Comparator<Person>//此时将类型制定为Person的,向上限定;  

{                                       //上面的Student、worker排序均可以使用;  

    public int compare(Person p1,Person p2)  

    {  

        return p1.getName().compareTo(p2.getName());  

    }  

}  

class Person  

{  

    String name;  

    Person(String name)  

    {  

        this.name = name;  

    }  

    public String getName()  

    {  

        return name;  

    }  

}  

  

class Student extends Person  

{  

    String name;  

    Student(String name)  

    {  

        super(name);  

    }  

}  

  

class Worker extends Person  

{  

    String name;  

    Worker(String name)  

    {  

        super(name);  

    }  



---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: